Why I looked past domestic PGs
I applied six times to Toss Payments to attach a checkout to a service I was building, and was rejected every time. Only one of those six came with a reason. The last one came back as "under review" and nothing further, and for the remaining four I still do not know why. Issuer underwriting criteria are not public, so no specifics are communicated. Failing six times and knowing the reason for only one of them is the shape of this process. It is not a matter of fixing paperwork — you cannot predict whether you will pass, so there is no plan to reapply against.
Stripe was the next candidate. But a Korea-based business cannot open a Stripe account. Stripe's own global availability page lists 32 European countries, and in Asia-Pacific covers Australia, Hong Kong, Japan, Malaysia, New Zealand, Singapore and Thailand, with India and Indonesia marked invite-only. Korea appears in neither list (checked 2026-08-06).
Put those together and the field narrows. The domestic route is blocked by underwriting; Stripe is blocked by geography. What remains is an overseas merchant-of-record platform, and Creem is one of them.
Worth noting: this is a regulatory problem, not an engineering one. However well the code is written, a service cannot take money without a payment contract. Vibe-coded projects that ship login and features usually stall exactly here.
| Item | Toss Payments | Stripe | Creem |
|---|---|---|---|
| Opening an account from Korea | Requires merchant underwriting | Korea not on supported list | Sign up, create a store |
| Seller of record | You | You | Creem (MoR) |
| Cross-border tax filing | Yours | Yours | Creem, 190+ jurisdictions |
| Refunds and disputes | Yours | Yours | Handled by Creem |
| Published fee | Per contract | Per contract | 3.9% + $0.40 |
What merchant of record actually means
Merchant of record (MoR) is the legal entity that sells to the end customer. Creem's documentation describes its own role as "the legal entity responsible for selling goods or services to end customers." On paper, the customer buys from Creem, not from you.
That is the difference from an ordinary payment gateway. A gateway rents you the card rails. You remain the seller, so tax filing, refunds and disputes stay with you. An MoR steps into the seller's seat entirely.
So Creem's list of responsibilities is concrete: payment processing, tax compliance across markets, sales tax collection and remittance, refund and chargeback management, tax calculation and collection in 190+ jurisdictions, compliant invoicing, and tax reporting. Anyone who has sold software to overseas customers knows why that list is welcome. EU VAT alone varies by country in both rate and filing cadence.
There are two costs. The fee runs higher than domestic card rates, and the customer's card statement shows CREEM rather than your service name. The second one comes up often enough that Creem publishes a customer-facing page titled "Why did Creem charge me." A single line on the product page and in the receipt email — payments are processed by Creem — heads off most of those questions.
The shortest path with no code
You can reach a working checkout without writing anything. Creem keeps a separate no-code path and names its audience in the docs: creators and vibe coders.
First, sign up at creem.io. No credit card is required to create the account. Once in, create a store.
Second, turn on test mode. You can run the full payment flow end to end without real money moving. Stay there until you are ready to go live.
Third, create a product in the Products tab of the dashboard. Give it a name, description and price. Choose single payment or subscription, then set currency and category. For a file-delivered product like an ebook or a template, upload the file here. When payment completes, a download link goes to the buyer's email automatically.
Fourth, hit the Share button on the product to get a payment link. Paste that URL into an email, an Instagram bio, or the end of a blog post, and checkout opens. That is as far as you can get without a single line of code.
That path alone is enough to sell ebooks, templates or course material. It also inverts the usual order: instead of building a site and then attaching payments, you can sell through a link first and build the site once there is demand.
Attaching it in code — four steps on Next.js
To open the checkout inside your own site, you need exactly two things: an API key and a product ID.
Step one, get the API key from the Developers menu in the dashboard. Copy it into a .env file at your project root as CREEM_API_KEY. Never put this key in frontend code or in a git repository — confirm .env is listed in .gitignore first.
Step two, install the adapter. Next.js has a dedicated one, which is the shortest route. On another framework, use the TypeScript SDK (npm install creem); in another language entirely, call the REST API directly.
Step three, create the checkout route. One file, app/api/checkout/route.ts, is enough. Keep testMode: true while testing and flip it to false when going live.
Step four, wrap your button. Pass the product ID from the dashboard — it starts with prod_ — into the component, and that button becomes the checkout button.
Run npm run dev, click the button, and Creem's checkout opens. In test mode, card number 4111 1111 1111 1111 with any future expiry and any three-digit CVC completes the payment. You are returned to the success page with checkout_id, order_id, customer_id and product_id appended as query parameters.
CREEM_API_KEY=creem_test_your_api_key
CREEM_WEBHOOK_SECRET=whsec_your_webhook_secret
NEXT_PUBLIC_APP_URL=http://localhost:3000npm install @creem_io/nextjsimport { Checkout } from "@creem_io/nextjs";
export const GET = Checkout({
apiKey: process.env.CREEM_API_KEY!,
testMode: true,
defaultSuccessUrl: "/success",
});import { CreemCheckout } from "@creem_io/nextjs";
export default function Page() {
return (
<CreemCheckout productId="prod_YOUR_PRODUCT_ID">
<button>Buy now</button>
</CreemCheckout>
);
}Webhooks: automating what happens after payment
Do not unlock the product on the strength of a redirect alone. If the buyer closes the tab right after paying, your server never learns the payment happened. Conversely, anyone who discovers the success URL can open it directly. Production integrations use webhooks.
A webhook is Creem's server telling your server directly that a payment finished. It does not travel through the buyer's browser, so it arrives even if the tab is closed.
Take the webhook secret from the dashboard into CREEM_WEBHOOK_SECRET in .env, and add one more route. The signature check that returns 401 on failure is the important part — without it, anyone can forge a payment-completed request and walk off with the product.
Three events are enough to start. checkout.completed fires when a payment finishes, subscription.active when a subscription starts or renews, and subscription.canceled when it ends. Grant access, keep it, revoke it, respectively.
import { NextRequest, NextResponse } from "next/server";
import { constructWebhookEventEntity } from "creem/webhooks";
export async function POST(request: NextRequest) {
const body = await request.text();
const event = await constructWebhookEventEntity(body, request.headers, {
secret: process.env.CREEM_WEBHOOK_SECRET!,
}).catch(() => null);
if (!event) {
return NextResponse.json({ error: "Invalid signature" }, { status: 401 });
}
switch (event.eventType) {
case "checkout.completed":
// grant access, send email, update the database
break;
case "subscription.active":
break;
case "subscription.canceled":
// revoke access
break;
}
return NextResponse.json({ received: true });
}Before you go live
Turn test mode off. If you are calling the REST API directly, also switch the host from test-api.creem.io to api.creem.io. With the adapter, set testMode to false. Miss this and no real payment ever arrives while the screen looks perfectly fine.
Budget the fee: 3.9% + $0.40 per successful transaction, with the docs stating no monthly fee, no setup cost and no hidden charges. That is not cheaper than domestic card rates. Read it as the price of handing off tax filing, refunds and disputes. The fixed $0.40 weighs more on low-priced items, so a catalogue of one- or two-dollar singles is better redesigned as bundles or a subscription.
Verify seller eligibility yourself. Creem's public documentation does not state which countries sellers may be based in, whether business registration is required, what identity verification is asked for, or how and when payouts happen. The "190+ countries" figure refers to tax jurisdictions on the customer side, not to seller eligibility. This article does not assert otherwise. Since signup needs no credit card, the fastest check is to create an account and read the onboarding screens.
Check payment methods. The platform centres on USD and international cards, so Korean rails such as KakaoPay, NaverPay and bank transfer are weak. If your buyers are mostly Korean and paying small amounts, this may be a poor fit. If you are selling software or digital goods to overseas customers, it is the right tool to begin with.
Warn about the statement descriptor in advance. That is the CREEM line above; one sentence on the product page and in the receipt email resolves most of it.
