Project-as-code for a Directus v9 backend

In practice, turning Directus into the backbone of a production backend takes a fair amount of setup before a project becomes productive. Projen, a project scaffolding and automation framework, can automate that plumbing, so the time the tech teams ‘d otherwise need to spend wiring Dockerfiles and build pipelines together goes into writing product and business logic instead.

@wbce/projen-d9 is the projen template we built to automate that plumbing around directus. By default it targets d9 (directus version 9), but you can adapt it to whichever Directus version you actually run. You can also customize it further to fit whatever your team needs. This post walks through what it generates and why.

d9 is a GPL fork of Directus v9 we maintain on GitHub. It does what Directus 9 did: an open-source (GPL-3 license) CMS that, with the right discipline, can stand in for a full custom backend (API, admin UI, permissions, schema), with business logic added as extensions (hooks, endpoints, operations, custom UI panels).

Bootstrap a new project

npx projen new --from @wbce/projen-d9

This creates a .projenrc.js and synthesizes the project.

What you get

The user-facing surface of the template is .projenrc.js:

import { D9Project } from '@wbce/projen-d9';
import { D9ExtensionType } from '@wbce/projen-d9-extension';

const project = new D9Project({
  name: 'my-backend',
  defaultReleaseBranch: 'main',
});

project.addExtension('audit-log', [D9ExtensionType.HOOK]);

project.synth();

npx projen synthesizes everything else (Dockerfile, docker-compose, extension folder, build pipeline, GitHub workflows). projen calls this “project-as-code”: project files are outputs synthesized from a config you commit, you re-synth whenever the config changes, and the generated files keep tracking the config over time.

Generated tasks

Task Description
first-run Bootstrap a complete local dev environment in one cli command
run Start d9 (docker compose up directus)
build-extensions Install and build all extensions
create-an-admin Create the default admin user

What gets generated

  • docker-compose.yml: d9, Postgres (PostGIS), Redis
  • Dockerfile: Node 22 + pnpm, builds extensions
  • .env.local: sample for local environment overrides
  • extensions as a pnpm workspace
  • GitHub PR and issue templates via
    @wbce/projen-shared (set
    githubConfig: false to disable)

A standardized compose stack

With a single CLI command, you can spin up a fully working local Directus environment (database, cache, and API) ready for development. It mirrors a production setup, including caching and geospatial capabilities.

The compose file is built with projen’s DockerCompose construct:

  • database: postgis/postgis:13-master in order to enable geospatial functionality
  • cache: redis:6
  • directus: built from the local Dockerfile. EXTENSIONS_AUTO_RELOAD=true is set, so re-running npx projen build-extensions is enough to pick up edits with no container restart.

Bind mounts:

  • ./uploads -> /app/uploads
  • ./extensions -> /app/extensions (the extension tree that build-extensions writes into)
  • ./.env.local -> /app/.env.local (so secrets stay out of the image and git versioning)

Extensions as a pnpm workspace

addExtension(name, types, options?)adds an ExtensionFolder to the parent project. Each addExtension creates a D9ExtensionProject with three quirks:

  1. Its package.json gets the directus:extension field correctly configured.
  2. Its build task is rewritten to compile and then deposit the output in the right subfolder of extensions/
  3. If any of the types are UI extensions (INTERFACE, DISPLAY, LAYOUT, MODULE, PANEL), vue is added as a devDep automatically.

Because every extension is its own package in a real pnpm workspace, we can share packages between extensions :

// A shared library, no extension types
project.addExtension('shared', []);

// Other extensions depend on it via workspace:
const myHook = project.addExtension('audit-log', [D9ExtensionType.HOOK]);
myHook.addDeps('shared@workspace:');

And pnpm catalogs in pnpm-workspace.yaml let you pin shared dependency versions in one place and consume them as catalog: from each extension’s package.json.

Deploying

The generated Dockerfile is meant for deployment. Build and push it to your
registry, then run it against your target database and cache.
Simple and efficient, the Docker setup ensures extensions are built inside the image during the build step.

FROM node:22-bookworm-slim
RUN npm install -g [email protected]
RUN npm install -g [email protected]
COPY package*.json /app/
WORKDIR /app
RUN NODE_ENV=production npm install
COPY . .
RUN npx projen build-extensions
CMD ["npx", "directus", "start"]

Integrate into an existing project

Follow this section of the documentation

Links

Issues and PRs welcome.

A 30-day playbook for building internal AI teams in SMBs

We’ve open-sourced a 30-day playbook for SMBs (10-100 people) looking to build their own internal AI capability. It’s a free document with reference Python notebooks, available at [github link].

After 12 engagements with SMBs in Asia and the US, we kept seeing the same three failure modes: teams treating AI as a magic box, starting with tools instead of problems, and attempting to boil the ocean. This playbook is our attempt to address those patterns.

The document structures a month-long rollout across four weeks: problem scoping and data inventory (week 1), model selection and prototyping (week 2), integration and workflow design (week 3), and team scaling and governance (week 4). It includes four reference notebooks covering data preparation, prompt engineering, model evaluation, and deployment patterns. Three case study writeups show how teams applied this framework to real problems in customer support and operations.

What’s not included: no SaaS platforms, no tool recommendations, no promises of “AI transformation.” We’re not selling anything—just sharing what’s worked in the field.

The playbook comes from 12 engagements across different industries. The sample size is small, and we’re sharing it to get feedback from others doing this work. We expect it will need refinement as more teams experiment with this approach.

We’re particularly interested in hearing about patterns we’ve missed, assumptions that don’t hold in other contexts, and alternative approaches that have worked for others. The GitHub repo includes an issues section for structured feedback.

This piece is from our notes on helping SMBs (10-100 people) build their first in-house AI teams. If your team is exploring this — quick feedback and questions welcome in the comments.

I finally shipped the plugin I’d been putting off for years. Then I started questioning why I built it.

A few days ago I checked off something that had been sitting in my todo list for a long time.

It’s a small develop plugin called unplugin-drop-committed. It removes method calls like console.log from your code during development — but only the ones that have been committed to Git. Your uncommitted lines are safe.

The idea came from a real frustration: a colleague had left console.log calls inside polling loops. The browser console was unusable. I didn’t want to ban console.log globally — I just wanted the committed noise gone.

Simple enough concept. I had the idea. I never built it.

Why it sat there so long

I care deeply about DX tooling. Probably more than is professionally sensible. I’ve filtered job opportunities based on whether I’d be working on developer experience. I think it’s underrated craft — the invisible layer that makes other developers’ days slightly less painful.

But DX is almost always low priority at work. There’s always a feature to ship, a bug to fix, a deadline to hit. The DX improvements I want to make get pushed to “later”. Later becomes the weekend. The weekend fills up. The todo list grows.

unplugin-drop-committed sat there for a long time. Not because it was hard. Because I never had the uninterrupted time to start.

How AI changed that

I used Claude to help me build it. I want to be clear about what that means: the ideas, the design, the four removal modes — those were mine. What AI gave me was momentum. It handled the boilerplate, suggested approaches I hadn’t considered, and kept me from getting stuck on implementation details that would have cost me a whole evening.

It took a fraction of the time I expected. I finally crossed something off the list.

For someone like me — someone with a backlog of DX ideas and a shortage of free hours — AI is genuinely liberating. It’s not replacing my thinking. It’s removing the friction that was keeping my thinking from becoming real things.

The question that followed

The satisfaction lasted maybe ten minutes.

Then I started thinking about who would actually use this.

AI-assisted development is changing how code gets written. AI agents don’t forget to delete their console.log calls the way humans do — or if they produce noise, it’s a different kind. The problem this plugin solves is a human problem, shaped by human habits.

I asked Claude how I should position the plugin. It suggested: “unplugin-drop-committed helps AI coding agents stay focused — keeping debug output isolated to the module being worked on.”

That’s… not wrong. It’s actually an interesting reframe. But it also felt like I was watching my motivation quietly shift from “making developers’ lives better” to “making AI agents’ workflows cleaner.”

DX. AX. Developer Experience. Agent Experience.

I’m not sure when the transition happened, or if it already has.

What I actually believe

I don’t think DX is dead. I think the audience is changing, and the best DX tools will be the ones that serve both humans and the agents working alongside them.

I also think there’s something worth preserving about caring whether the developer console is readable. Whether the hot reload feels instant. Whether configuration is intuitive. These things still matter, even if fewer people are writing the code by hand.

And I’m going to keep building these tools. AI gave me back the time to do it. I’d rather use that time on the things I actually care about than spend it wondering whether caring still counts.

If you want to try it:

https://github.com/KID-joker/unplugin-drop-committed

Four modes: strict (committed lines), file (committed files), user (other authors), time (older than N days/months). Vite, Webpack, Rollup, Rspack. Vue and Svelte script blocks included.

I’d genuinely like to know: do you think DX tooling still matters the same way it did two years ago?

Google, Gemini için “CapCut” ile iş birliği gerçekleştirdi

Google, Gemini için CapCut ile iş birliği gerçekleştirdi

Google, Gemini için CapCut ile iş birliği gerçekleştirdiGoogle, I/O 2026’da çok büyük duyurular yaptığı Gemini için CapCut ile iş birliği gerçekleştirdiğini duyurdu. Bu konuda yapılan resmi açıklamada, “Kullanıcılar yakın zaman içerisinde CapCut’ın gelişmiş düzenleme yeteneklerini kullanarak doğrudan Gemini uygulaması içerisinde fotoğraf ve video düzenlemeleri yapabilecek. Bu iş birliği sayesinde yaratıcı iş akışları daha bağlantılı ve kusursuz hale gelecek. Araçlar arası akıllı entegrasyonla içerik üretim süreçlerinin gelecekte daha sezgisel, diyalog tabanlı ve kesintisiz bir yapıya kavuşacağına inanıyoruz. Bu henüz sadece bir başlangıç.” ifadelerine yer verildi.

Google, Gemini için “CapCut” ile iş birliği gerçekleştirdi yazısı ilk olarak Teknoloji haberleri – LOG üzerinde yayınlandı.

When the API literally burned your database after a typo

The Problem We Were Actually Solving

We needed a staging environment that could tolerate the stupidity of humans. Not a toy cluster that looked like production but couldnt survive a mis-typed curl flag. The real requirement was: if an engineer turns staging into a dumpster fire at 3 am, nothing outside staging should notice. We also needed to ship a new subscription checkout flow for creators in countries where PayPal blocks transactions. The flow had to store settlement schedules, retry failed charges, and emit events to Kafka so analytics could bill creators in USD without touching the blocked jurisdiction. The first cut used DynamoDB with on-demand capacity and TTLs, but the finance team vetoed it because the eventual-consistency model could under-charge a creator in Kazakhstan by 0.03 USD and we wouldnt know for 12 hours.

What We Tried First (And Why It Failed)

We started with a Terraform module for RDS Postgres 14, parameter group set to db.t3.medium, publicly accessible = true, and storage_encrypted = false. It passed the linting stage because the linter only checked for AWS tags. We deployed staging with terraform apply -auto-approve -var environment=staging. Two weeks later an intern ran a chaos experiment that killed the master node; Prometheus screamed about 503s on /health but the auto-scaling policy had cooldown = 300 seconds and the replacement node took 7 minutes to come up because the init script downloaded 1.2 GB of fonts for a demo dashboard. The payment service still didnt retry DNS, so the first 480 requests failed.

We also tried a separate staging Kafka cluster (msk.t3.small, three brokers) to test exactly-once semantics. The topic auto-created with retention.ms=604800000, which meant a single misconfigured producer could retain a week of test messages and run the cluster out of disk in six hours. Kafka Manager showed the disk usage in red, but the on-call rotation had no threshold rule for broker disk < 30 GB. The staging alert router pointed to a Slack webhook that posted to #staging-alerts; the channel had 477 muted threads and the message was scrolled away before anyone noticed.

The Architecture Decision

We rebuilt staging to be disposable and observable.

First, we replaced the Terraform RDS module with an ephemeral Postgres in Kubernetes using the zalando/postgres-operator. The operator runs a primary pod with a sidecar pgbouncer, a standby set, and a volume snapshot every hour. The snapshot lands in an S3 bucket with SSE-KMS, so even if the cluster melts, a simple kubectl apply -f restore.yaml brings it back in five minutes. We turned publicly accessible off and added an AWS PrivateLink endpoint so the Kubernetes cluster could reach the DB without an internet gateway. The terraform apply now uses –target=module.vpc –target=module.eks first to prevent route table race conditions.

Second, we moved the checkout retry logic from HTTP to a durable queue. Instead of the legacy PHP helper that multiplied null by a million, we wrote a Go service that consumes from an SQS FIFO queue named checkout-payments.fifo with message group ID set to the creators UUID. The queue has visibility timeout 300 seconds and maximum receive count 3. The service writes to Postgres in a transaction, then publishes a Kafka event only after commit. We disabled TTL on the queue because we never want a subscription schedule to evaporate during an outage. The service exports a Prometheus metric checkout_service_retry_count{queue=fifo} that fires an alert if the count > 5 per minute.

Third, we built a nightly chaos pipeline that runs in staging: it randomly kills the Postgres primary, injects 500 ms latency on the PrivateLink, and rewrites a checkout row to status=failed_then_retry=true. The pipeline is scheduled by GitHub Actions at 02:00 UTC and posts results to a dedicated Slack channel. If the primary doesnt recover within five minutes, the pipeline pages the on-call rotation. The chaos job uses terraform destroy -target=module.staging_db followed by terraform apply to ensure

Treated the payment platform as infrastructure. Found the single point of failure. This is the replacement I put in place: https://payhip.com/ref/dev4

COOKIES

Cookie: How website remember us

During a TED Talk I led a session on one of the most important but often ignored parts of the internet- cookies. Many people hear the word “cookie when browsing or they may see it and still ignore it yet they don’t know how they work behind the scenes.

What Are Cookies?
Cookies are small data stored in your browser to help the website to remember information about you.
Since websites cannot naturally remember visitors after page refresh, cookies act 4like a memory tool between the browser and the server.
For example, when you log into a website and remain signed in even after refreshing the page, cookies are usually responsible for that experience.

How cookies work

Cookies work through communication between a web browser and a web server.
The process is simple:

  1. A user visits a website ,(search any kind of website)
  2. The user inputs his/her credential like : password, username/email.
  3. These credentials are sent to the database for verification.
  4. After verification a session is created with a unique ID called session ID.
  5. The website creates a cookie containing information as a session ID or user preference.
  6. The cookie is stored in the browser.
  7. Every time the user revists the website, the browser sends the cookie back to the server.
  8. The server reads the cookie and recognizes the user.
    This allows websites to provide personalized experience without asking users to log in repeatedly.

For example,

  • Online stores remember items in a cart.
  • Social media platforms keep users logged in.
  • Websites remembers language or theme preferences.
    Without cookies, users would have to re-enter information on every page they visit.

Types of cookies

During the session, I explained that cookies are divided into different types depending on their purpose.

1. Session cookie

Session cookies are temporary that only exist when the browser is still open , once the browser is closed the cookie expires automatically.

They are mainly used for :

  • 1. Keeping users loigged in during one session.
  • 2. Temporary website activities.
  • 3. Navigation between pages.

Persistence cookie

This cookie remain stored for a longer period of time maybe weeks or months even after the browser is closed.

They are mainly used for:

  • Login details.
  • User preferences.
  • Frequently visited settings.

3. Third-Party cookie

Third-party cookies are created by external companies such as advertisers or analytics services instead of the website itself.

They are mostly used for:

  • Tracking browsing behavior
  • Showing targeted advertisements
  • Collecting website analytics

These cookies are the main reason privacy concerns around cookies exist today.

Why cookies are important

Cookies make the internet faster, easier, and more personalized. They improve user experience by helping websites remember useful information.

However, cookies also collect data about user activity. Some websites use this information responsibly, while others may use it for aggressive advertising and tracking.

This creates an important conversation about privacy, data security, and digital awareness.

Privacy and security concerns

One major topic discussed during the TED Talk session was how cookies can affect privacy.

If not properly protected, cookies can:

  • Be used to track user activity online
  • Store sensitive information
  • Become targets for hackers
    Modern websites now use security measures such as:

  • Encrypted HTTPS connections

  • Secure cookies

  • Cookie consent notices

  • Privacy settings for users
    Many browsers also allow users to block or delete cookies whenever they choose.

Conclusion

Cookies may seem small, but they are essential to how the modern web works. They help websites remember users, maintain sessions, personalize content, and improve browsing experiences.

At the same time, they raise important questions about privacy and data tracking. Understanding how cookies work helps users become more informed and responsible internet users in today’s digital world.

DPRK Hacking Trends 2026: AI‑Powered Supply Chain and Developer Environment Attacks

DPRK Hacking Trends 2026: AI‑Powered Supply Chain and Developer Environment Attacks

Date: 2026-05-21 | TLP:CLEAR | Report ID: CTI-2026-0521-DPRK-TRENDS

North Korean state‑sponsored hacking groups (Lazarus, Famous Chollima, Kimsuky and their sub‑groups) have entered a new phase of operation in 2026. Three distinct but interconnected trends define their current playbook: industrialised supply chain attacks, AI‑enabled intrusion campaigns, and direct targeting of the developer environment (npm, VS Code, IDEs). Together, these axes form a single, converged workflow that begins with fake job interviews and ends with the theft of cryptocurrency, code‑signing certificates, and credentials from downstream customers.

1. Supply Chain Attacks – Reaching the Unreachable

In March 2026, the Lazarus Group (BlueNoroff) socially engineered the lead maintainer of axios – a JavaScript HTTP client with ~70 million weekly downloads – and published two malicious versions (v1.14.1 and v0.30.4). The blast radius was extraordinary: OpenAI’s macOS app‑signing GitHub Actions workflow pulled the infected version, giving the attackers access to the code‑signing certificates for ChatGPT Desktop and Codex without ever touching OpenAI’s own systems. The malicious packages were removed within hours, but axios resides in approximately 80% of cloud and code environments and is downloaded about 100 million times per week, enabling rapid exposure in about 3% of affected environments.

Only weeks later, on April 30, 2026, PyTorch Lightning – one of the world’s most widely used AI/ML frameworks – was found compromised in a supply chain attack designed to steal credentials. Security experts now characterise these incidents not as one‑off backdoors but as industrialised supply chain campaigns, urging defenders to treat supply chain security as seriously as application security.

2. AI‑Enabled Attacks – Collapsing the Barrier to Entry

The most notable AI‑driven case is HexagonalRodent (Expel‑TA‑0001), a subgroup within the Famous Chollima / Lazarus ecosystem. Over three months, the group targeted more than 2,000 developers working on cryptocurrency, NFT, and Web3 projects and is estimated to have stolen roughly $12 million using AI‑generated malware and phishing infrastructure.

Marcus Hutchins, the researcher who discovered the group, noted that the most striking thing about the campaign was not its sophistication but how AI tools let an apparently unsophisticated group carry out a profitable operation. They “vibe coded” nearly every part of their intrusion campaign – from writing malware to building fake company websites – using OpenAI, Cursor, and Anima. AI lowered the barrier to entry so dramatically that tasks once requiring fluent language skills, sophisticated code modification, and careful persona management have now been partially “outsourced” to commercial AI tools.

AI is also used at the intrusion stage: Famous Chollima employs AI deepfakes and stolen identities in fake job interviews to infiltrate crypto and Web3 companies. Kimsuky used ChatGPT to generate a fake South Korean military ID (bypassing platform restrictions) and ran a phishing campaign targeting journalists, researchers, and human rights workers.

3. Attacks on the Developer Environment – The New Perimeter

The Contagious Interview campaign, ongoing since November 2023, is the representative case. DPRK‑linked actors uploaded 197 new malicious npm packages distributing an updated OtterCookie variant, accumulating over 31,000 downloads. The campaign targets developers on Windows, Linux, and macOS – especially those in crypto and Web3. The attack structure is a compartmentalised “factory”: GitHub for source control, Vercel for payload staging, npm for distribution, and a separate C2 tier.

Installing the malicious packages prompts a connection to a hardcoded Vercel URL and retrieval of OtterCookie, which bypasses VMs and sandboxes before providing a remote shell and enabling clipboard theft, keystroke logging, and theft of browser credentials and crypto wallet data. The latest variant (tracked since October 2025) introduces much heavier obfuscation – hiding strings, URLs, and logic through encoded index lookups and shuffled arrays – making static and signature‑based detection substantially harder.

The evolution of using the IDE itself as the execution trigger is seen in the HexagonalRodent case. Attackers post high‑paying roles on LinkedIn and Web3 recruitment platforms, luring job seekers into malware‑laced “skills tests” that abuse VS Code’s tasks.json feature – malicious code auto‑executes the moment the victim opens the project folder. In early 2026, HexagonalRodent also compromised the popular VS Code extension “fast‑draft” to distribute OtterCookie, the first confirmed instance of this subgroup conducting a supply chain attack – suggesting it is expanding its methods and growing in technical confidence.

4. Synthesis – The Converged Workflow

Stage Tactic Representative Tools / Cases
Access Fake recruitment/interviews, deepfake identity Famous Chollima, fake Lever job portal
Weaponisation Mass‑produce malware/phishing infrastructure with AI ChatGPT, Cursor, Anima
Execution Trigger via dev environment (npm / VS Code) OtterCookie, BeaverTail, tasks.json
Propagation Penetrate trusted packages → downstream axios, fast-draft, PyTorch Lightning
Monetisation Credential/wallet theft $12M (HexagonalRodent), Bitrefill, etc.

The most important insight is not the “AI‑built super hacker” narrative. The most credible part of the story is that DPRK‑linked operators are using AI as a force multiplier within already‑proven social‑engineering and developer‑compromise workflows. AI did not invent new attacks; it acts as an amplifier that explosively scales the volume, speed, and accessibility of existing attacks.

5. Key Recommendations for Defenders

Area Recommendation
Developer Protection Make recruitment/coding‑test‑disguised approaches a core security‑training scenario. Mandate isolated environments (VM/container) before running “take‑home assignments”.
Dev Environment Review VS Code tasks.json auto‑execution, verify IDE extension provenance, enforce trusted‑workspace policies.
Supply Chain Use lockfile/hash verification for npm/PyPI dependencies, minimise secret access in build/signing pipelines (GitHub Actions), adopt SBOM.
Detection Signals Monitor unexpected clipboard access, keylogging, screenshot capture, system profiling, anomalous User‑Agents.
Credentials Treat developer workstation compromise as a potential funds‑loss event; on compromise, immediately revoke code‑signing certs and wallet keys.
AI Abuse Log internal AI tool usage; when adversarial AI abuse is identified, use vendor reporting channels (OpenAI, Cursor, etc.).

Full Report

For the complete Cyber Threat Intelligence (CTI) report – including detailed technical indicators, subgroup mapping, and all source references – please see the original analysis:

🔗 DPRK‑Linked Cyber Threat Trends H1 2026 – Full CTI Report (GitHub)

This post is based on open‑source intelligence (OSINT) and research from Expel, Microsoft, Mandiant, Socket, and other public sources. It is intended for defensive, educational, and policy purposes only.

Phone control for AI coding sessions is not a tiny terminal

Most mobile AI coding workflows eventually hit the same wall.

tmux keeps the process alive. SSH lets the phone attach. Remote desktop can show the whole screen. None of that means the phone is a good control surface.

On a phone, the common loop is much smaller:

  • see which Codex, Claude Code, or shell session is alive
  • read the last meaningful output without parsing a full terminal wall
  • send a short nudge back into the same running process
  • approve or reject a blocked action
  • interrupt when the agent is clearly going wrong
  • hand the context back to the desktop without creating a second history

That is the gap I built Faryo for.

Faryo is an open-source phone/browser workbench for tmux-backed AI coding sessions. The local tmux session stays the source of truth. Codex CLI, Claude Code, or a plain shell keeps running on the host. The phone/browser layer is deliberately thin: compact output, short input, approve/interrupt, and handoff.

It is not a remote desktop. It is not a cloud IDE. It is not another AI chat thread.

The narrow promise is: keep the same live terminal session, but stop forcing the phone to behave like a full terminal.

Repo: https://github.com/Snailflyer/faryo

PayPal and Crypto Are Not Equals: How I Built a Gumroad Alternative for Restricted Countries

The Problem We Were Actually Solving

I still remember the day I realized that the e-commerce platform I was building for creators would not work in several countries due to payment gateway restrictions. It was not just a minor inconvenience, but a major roadblock that would affect thousands of potential users. As I delved deeper into the issue, I found that popular platforms like PayPal, Stripe, Gumroad, and Payhip were not available in many countries, leaving creators with limited options. This was a platform problem, not a user problem, and I was determined to find a solution.

What We Tried First (And Why It Failed)

My initial approach was to use PayPal as the primary payment gateway, with Stripe as a fallback option. However, I quickly realized that this approach would not work for creators in restricted countries. The error messages were clear: PayPal’s API would return a 402 error, indicating that the transaction was declined due to geographical restrictions. Stripe’s API would return a similar error, with a 20003 error code indicating that the card was not supported. I tried to use workarounds, such as using VPNs or proxy servers, but these solutions were not scalable or reliable. It became clear that I needed to explore alternative payment methods that could bypass these restrictions.

The Architecture Decision

After conducting extensive research and testing, I decided to integrate a cryptocurrency-based payment system into our platform. This decision was not taken lightly, as it required significant changes to our architecture and infrastructure. I chose to use the Coinbase API, which provided a robust and secure way to process cryptocurrency transactions. I also implemented a system to convert fiat currencies to cryptocurrencies, using the ExchangeRate-API to fetch the latest exchange rates. This approach allowed creators to receive payments in their local currency, while also providing a secure and reliable way to process transactions.

What The Numbers Said After

The results were impressive. Within the first month of launching our cryptocurrency-based payment system, we saw a 30% increase in transactions from restricted countries. The average transaction value also increased by 25%, indicating that creators were able to sell more and earn more on our platform. The error rate decreased significantly, with only 2% of transactions failing due to technical issues. In contrast, our previous PayPal-based system had an error rate of 15%. The numbers clearly showed that our decision to use cryptocurrency-based payments was the right one.

What I Would Do Differently

In hindsight, I would have started with a cryptocurrency-based payment system from the beginning. The time and resources spent on trying to work around PayPal’s restrictions could have been better spent on optimizing our platform for cryptocurrency payments. I would also have explored more options for fiat-to-cryptocurrency conversion, as the ExchangeRate-API sometimes introduced latency and inconsistencies in our system. Additionally, I would have implemented more robust security measures to protect user funds and prevent potential scams. However, overall, I am pleased with the decision to use cryptocurrency-based payments, and I believe it has been a key factor in the success of our platform.

Exploring Tech as a Content Writer

Hello everyone!

I’m Dolapo, a content writer and email copywriter interested in remote work, digital tools, and technology. I recently joined the DEV Community with the goal of learning, sharing my discoveries, and growing through public writing.

I spend a lot of time learning how digital tools function and interact with people, but I wouldn’t consider myself a developer — at least not yet. Curiosity is what brought me here.

I joined DEV because I wanted a place where I could:

  • Learn from people creating real products
  • Understand the inner workings of tech tools
  • Write more effectively about digital tools and systems
  • Document my learning journey in an organized way

I’ve come to realize that many of the tools we use every day — apps, SaaS platforms, and automation systems — are built on concepts that can actually be understood simply. I enjoy breaking those ideas down in a clear and approachable way.

Right now, I’m learning about:

  • How SaaS tools combine communication and user experience
  • Automation systems and email marketing
  • Digital tools that support productivity and remote work
  • The basics of how tech products are positioned and explained

I’m especially interested in the “why” behind tools — not just how to use them, but also why they are designed the way they are.

Going forward, I’ll be sharing:

  • Simple breakdowns of tech tools and platforms
  • Beginner-friendly explanations of digital marketing and email systems
  • Lessons I learn while exploring remote work and tech-related skills
  • My experience learning how to write for tech and SaaS products
    My goal is to make complex topics feel easier to understand, especially for beginners like myself.

I’m here to learn, write, and grow in public.

If you’re also learning, building, or exploring technology in any way, I’d love to connect with and learn from you too.

What’s one important thing you think beginners in tech should understand early?