$topblogs
SaaS

Creem.io for Pakistani Developers: A Practical Integration Guide (2026)

Hanzla Baig
Hanzla Baig

September 28, 2026 · 14 min read

Creem.io for Pakistani Developers: A Practical Integration Guide (2026)

Picture this. You've spent four months on a small SaaS tool. It works, your friends say it's good, and a stranger in Germany has just asked where they can pay for it. You open Stripe, start the signup, and Pakistan isn't in the country list.

That moment is where a lot of Pakistani developers stall. Some give up. Some pay for a US LLC they don't really want. Some send customers a Payoneer link and hope for the best.

Creem.io is one of the newer platforms trying to fix that gap, and it does list Pakistan as a supported country. But "supported" hides a few details that decide whether it works for you. This guide walks through those details first, then builds a full integration with real code.

Last checked in September 2026. Payment rules change quickly, so confirm anything money-related on Creem's own docs before you commit. This article is independent and isn't sponsored by Creem.

What Creem actually does

Creem is what the industry calls a Merchant of Record. The term sounds heavier than it is.

Think of a shop that sells your product for you. When a customer in France buys, the shop is the one legally selling to them. It charges the card, works out the French VAT, sends the invoice, and deals with the bank if the customer disputes the charge. Then it pays you what's left after its cut. With a normal payment processor like Stripe, you are the seller, so all of that lands on you.

Creem is built by Armitage Labs OU, an Estonian company, and it targets software and digital goods. The API covers products, hosted checkout pages, customers, subscriptions, discount codes, and license keys. If you sell a SaaS plan, an extension, a template pack, or an ebook, you're the intended customer.

So, does it work in Pakistan?

Yes. Pakistan is on Creem's list of supported merchant countries, and buyers in Pakistan can purchase from you too, since Pakistan isn't on the unsupported list.

Now the catch. On that list, Pakistan carries a double asterisk. The docs say countries with that mark may face restrictions from Creem's bank transfer partner, for example only personal bank accounts being accepted, or business transfers being unavailable.

The partner is Wise, and Wise's own help page for PKR transfers is blunt. It says you can send PKR to personal bank accounts in Pakistan, that you can't send to a business account, and it warns against a couple of account types, namely Meezan Bank Express and Allied Bank Express accounts, which reject these transfers.

Put those two facts together and you get a fairly clear picture.

If you're a freelancer or solo founder, onboarding as an individual with a personal PKR account in your own name is the path most likely to go smoothly. The name on the bank account has to match the name on your identity verification, because a mismatch is one of the documented reasons a payout bounces back.

If you run a registered company and want the money to land in a company account, don't assume it works. Email Creem support first and ask directly. It's a five-minute question that can save you weeks.

There's also a backup route. Creem pays out in USDC on the Polygon network for a 2% fee. If your bank keeps rejecting transfers, that's your escape hatch, though you'd need a wallet and a way to turn USDC into rupees that you trust.

What you can sell, and what will get you turned away

This part surprises people, so read it before you spend a weekend on integration.

Creem is for digital products. Its account review rules say services of any kind aren't accepted, and the examples they give include marketing, design, web development and consulting. So if your plan is to collect payment for client projects, Creem isn't the tool. That's a real limit for the many Pakistani developers who earn through freelancing.

Generative AI products, such as text-to-image or text-to-video tools, sit on a restricted list. Restricted doesn't mean banned. It means extra checks, and they'll ask about your previous payment processor, your refund rate, and why you're moving.

One more thing. Be honest about what you sell. Creem can ask for test access to your product and may make a small test purchase during onboarding. Sellers who hide things tend to get their accounts closed, and closed accounts with money inside are a miserable problem.

What it costs, in actual numbers

The headline rate is 3.9% plus $0.40 per successful transaction, with no monthly fee. On a $29 sale with no tax added on top, that's about $1.53 gone to the platform.

Some features cost extra. Revenue splits and the affiliate system each add 2%, and abandoned-cart recovery adds 5% on the recovered sale. If you don't turn those on, they don't touch you.

The number that matters most for someone in Pakistan is the payout fee, which is $7 or 1% of the payout, whichever is bigger. Run it on a few amounts and the trap becomes obvious.

Withdraw $100 and you lose $7, which is 7% of your money. Withdraw $700 and 1% comes to exactly $7, so that's the break-even. Withdraw $2,000 and the fee is $20, or a clean 1%.

So don't withdraw just because the 15th is coming. Let the balance build and take it out in bigger lumps. The minimum to request a payout is $50, and payouts run on the 1st and the 15th of each month.

Two timing details are easy to miss. New payments can be held for 7 to 12 days for risk review, which means a sale you make on the 12th usually won't be ready for the 15th. And if your bank account currency differs from the currency you charged in, the bank partner applies its own conversion fee, which Creem says it doesn't control.

Where I'd be cautious

A competitor's comparison post criticizes Creem's extra fees and says checkout supports only USD and EUR. That source sells a rival product, so treat it with salt, but the currency point is easy to verify yourself in the dashboard before you price anything.

There's also a small inconsistency worth knowing about. Creem's pricing page says automatic tax collection covers 50+ countries, while its homepage talks about compliance across 190+ countries. They may be describing different things, but if one particular market matters to you, ask support whether it's covered.

Trustpilot reviews lean positive on support and documentation, with some complaints about individual merchants' billing. That's normal for any payments company. Just don't rely on marketing pages alone.

Building the integration

I'll use Next.js and the official TypeScript SDK because that's what most people reach for. Creem also has a REST API, a Better Auth plugin, and a Convex component if your stack looks different.

Create your account and a test product

Sign up at creem.io, finish verification, then flip the Test Mode toggle at the bottom of the left sidebar. Everything in test mode is walled off from real money, which is exactly what you want while you're making mistakes.

Open the Products tab and create your first product. Set the name, the price, and whether it's one-time or recurring. Prices are stored in cents, so 1000 means $10.00. Choose a tax category (SaaS, digital goods, or ebooks) and a tax mode, inclusive or exclusive. Copy the product ID that starts with prod_. Then head to the Developers section and copy your API key.

Set up the environment

npm install creem
# .env.local
CREEM_API_KEY=your_test_api_key
CREEM_WEBHOOK_SECRET=whsec_your_webhook_secret
CREEM_ENV=test
NEXT_PUBLIC_APP_URL=http://localhost:3000

The API key belongs on the server only. Don't put it in browser code and don't commit it to Git. Test and live modes use different keys and different base URLs, https://test-api.creem.io for testing and https://api.creem.io for production.

Create the client

// lib/creem.ts
import { Creem } from "creem";

export const creem = new Creem({
  apiKey: process.env.CREEM_API_KEY!,
  ...(process.env.CREEM_ENV !== "production" && { server: "test" as const }),
});

When you leave server out, the SDK talks to production. This setup only forces test mode when you haven't said you're in production, which is a safer default than the reverse.

Create a checkout session

// app/api/checkout/route.ts
import { NextRequest, NextResponse } from "next/server";
import { creem } from "@/lib/creem";

export async function POST(request: NextRequest) {
  try {
    const { productId, userId, email } = await request.json();

    const checkout = await creem.checkouts.create({
      productId,
      successUrl: `${process.env.NEXT_PUBLIC_APP_URL}/success`,
      customer: { email },
      metadata: { userId },
    });

    return NextResponse.json({ checkoutUrl: checkout.checkoutUrl });
  } catch (error) {
    console.error("Checkout error:", error);
    return NextResponse.json(
      { error: "Could not create checkout" },
      { status: 500 }
    );
  }
}

That metadata line is easy to skip and painful to regret. Put your own user ID in it. When the webhook fires later, the same metadata comes back, so you know exactly which account in your database just paid.

On the front end, call the route and send the browser to the URL it returns.

async function buy() {
  const res = await fetch("/api/checkout", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      productId: "prod_YOUR_PRODUCT_ID",
      userId: currentUser.id,
      email: currentUser.email,
    }),
  });
  const { checkoutUrl } = await res.json();
  window.location.href = checkoutUrl;
}

Handle webhooks

This is the part that actually decides whether your app gets paid correctly.

Don't unlock anything just because someone reached your success page. Anyone can type that URL into a browser. The webhook is the only trustworthy signal that money moved.

Creem signs each webhook. The signature arrives in the creem-signature header, and it's an HMAC-SHA256 of the raw request body using your webhook secret. That's why you read the body as raw text before doing anything else with it.

// app/api/webhooks/creem/route.ts
import { NextRequest, NextResponse } from "next/server";
import { constructWebhookEventEntity } from "creem/webhooks";

export async function POST(request: NextRequest) {
  const rawBody = await request.text();

  const event = await constructWebhookEventEntity(rawBody, request.headers, {
    secret: process.env.CREEM_WEBHOOK_SECRET!,
  }).catch(() => null);

  if (!event) {
    return NextResponse.json({ error: "Invalid signature" }, { status: 401 });
  }

  // The same event can arrive more than once, so skip repeats.
  const eventId = JSON.parse(rawBody).id as string;
  if (await hasProcessed(eventId)) {
    return NextResponse.json({ received: true });
  }

  switch (event.eventType) {
    case "checkout.completed": {
      const userId = event.object.metadata?.userId;
      // Unlock the one-time purchase for this user.
      break;
    }
    case "subscription.paid": {
      // Activate or renew access for the paid period.
      break;
    }
    case "subscription.past_due":
    case "subscription.unpaid": {
      // Show a payment-recovery message and restrict access per your policy.
      break;
    }
    case "subscription.canceled": {
      // Revoke access.
      break;
    }
  }

  await markProcessed(eventId);
  return NextResponse.json({ received: true });
}

hasProcessed and markProcessed are stand-ins for your own database. A table with the event ID as a unique column is plenty.

A few details about how Creem behaves. Answer with HTTP 200 when you've handled an event. If you don't, Creem tries again, five attempts in total, after 30 seconds, 5 minutes, 30 minutes and 6 hours, and it stops after 24 hours. Its docs suggest using subscription.paid to switch on access and keeping subscription.active for syncing. Creem also doesn't publish fixed IP addresses for webhooks, so an IP allowlist won't protect you. The signature check is your protection.

If you'd rather skip the SDK helper, you can verify the signature by hand.

import crypto from "crypto";

function isValidSignature(rawBody: string, header: string, secret: string) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");

  const a = Buffer.from(expected);
  const b = Buffer.from(header ?? "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Test it locally

Creem needs a public HTTPS address to reach. While you're developing, the Creem CLI can forward events straight to your machine.

creem listen --forward-to http://localhost:3000/api/webhooks/creem

If you prefer a tunnel like ngrok, register that URL under Developers and then Webhooks in the dashboard. Add your production URL separately once you deploy.

In test mode, the card 4111 1111 1111 1111 gives you a successful payment with any future expiry and any CVC. The card 4507 9900 0000 0028 simulates a decline, and 4507 9900 0000 0010 simulates insufficient funds. Try the failing cards on purpose. Subscriptions especially tend to break in the unhappy paths, not the happy one.

Go live

Before you switch, walk through this once.

  1. Run every flow in test mode: a purchase, a failed payment, a cancellation, a refund.

  2. Swap in your live API key and drop the test server setting.

  3. Recreate your products in live mode, because test products don't carry over.

  4. Register your production webhook URL and copy the live webhook secret.

  5. Add your payout account and finish identity verification.

  6. Watch your first handful of real transactions closely.

Getting paid in Pakistan

Set up your payout account long before you need it. For a bank payout, expect to give your full name and your IBAN, which is what Wise asks for on PKR transfers. Use a personal account in your own name, and stay away from the Express account types mentioned earlier.

If a payout fails and the money returns to your balance, it's usually one of three things. The bank details are wrong. The account can't receive international payments. Or the account holder's name doesn't match the identity you verified with. Check those before opening a support ticket, because you'll likely find the answer yourself.

Mistakes that tend to bite

A few come up again and again with payment integrations, and Creem is no exception.

Granting access from the success page is the big one. It feels fine in testing and then someone shares the URL. Use the webhook.

Parsing the request body before verifying the signature is another. Once a framework re-serializes the JSON, the bytes change and the signature check fails for no obvious reason. Read the raw text first.

Mixing environments causes the strangest errors. A test key pointed at the production endpoint, or the other way round, fails in ways that look like bugs in your own code. Check your environment variables before you start debugging logic.

And then there's the small, quiet one. Withdrawing $60 because you're impatient and losing $7 of it. Wait a month.

Your own taxes

Creem, as Merchant of Record, handles sales tax and VAT on what your customers buy. It doesn't handle your income tax in Pakistan. Those are separate worlds.

Each payout comes with a reverse invoice, which is useful paperwork, so download and keep them along with your bank credit records. How foreign income is taxed for freelancers and software exporters in Pakistan has its own rules and they change over time. Talk to a qualified accountant instead of trusting a blog post, this one included.

Who should use it

Creem makes sense if you sell a SaaS product, browser extension, template pack, ebook or licensed software, if a personal bank account in your own name works for you, and if you'd rather not learn how to file taxes in a dozen jurisdictions.

It's the wrong tool if most of your income is client work, if you need money to land in a business account, if you need to be paid more often than twice a month, or if your product sits in a restricted category.

Whichever way you lean, test with something small. List a cheap product, complete one real sale, and follow that money all the way into your bank account before you build anything bigger on top. Watching your own first payout arrive will tell you more than any review, including this one.

Frequently asked questions

Is Creem available in Pakistan? Yes. Pakistan is on the supported merchant country list, with a note that bank partner restrictions may affect payouts.

Can customers in Pakistan buy from a Creem checkout? Purchases are accepted from every country except those on Creem's unsupported list, and Pakistan isn't on it. Which payment methods appear depends on the buyer's location, the product type, the price and the device.

Do I need a registered company? No. Creem accepts individual sellers, who go through standard identity checks. Individuals need a payout account in the same name as their verified identity.

How does the money reach me? Through a local bank transfer handled by Creem's bank partner, or through USDC on Polygon. Payouts run on the 1st and 15th of each month.

What's the minimum payout? Your balance has to reach $50 or 50 EUR before you can request a withdrawal.

Can I collect payment for freelance projects with it? No. Services such as consulting, design and web development aren't accepted. Creem is designed for digital products.

Does it work with Next.js? Yes. There's an official TypeScript SDK and a dedicated Next.js adapter, plus a Better Auth plugin and a Convex component.

Sources and last checked

Everything factual above was checked in September 2026 against these official pages: Creem's Supported Countries, Payouts, Quickstart, Test Mode and Webhooks documentation, its Pricing page, Terms of Service and Account Reviews policy, and Wise's help article on PKR transfers. Rules on all of these can change, so double-check current details before you make decisions.

Disclaimer: This article is general information, not financial, legal or tax advice.

Frequently asked questions

More to read