Skip to content
Gaurav TiwariDocs

Sell Through Creem as Merchant of Record

Updated November 7, 2026

Selling software or digital downloads to buyers abroad means VAT across Europe and sales tax in a growing list of US states, each with its own registration and filing. For a small store, that paperwork can cost more than the sales it covers.

Creem is a merchant of record: it sells to the buyer, works out the tax and remits it. With the Creem module, buyers pay on Creem’s hosted checkout by card, Apple Pay or Google Pay, Creem bills and renews subscriptions, and orders stay in step through signed webhooks that Stackless sets up for you.

Turn On the Gateway

  1. Switch on the Creem module under Stackless → Dashboard.
  2. Go to WooCommerce → Settings → Payments → Creem (Stackless).
  3. Tick Enable (Accept payments with Creem).

Stackless → Settings → Creem only shows a link to that screen and your webhook URL. Creem stays off the checkout until the current mode has an API key.

Add Your API Keys

In the Creem dashboard, open Developers and copy your API key. The Get API keys button on the settings screen opens the same page. Test and live keys are separate: switch on Test Mode at the bottom of Creem’s sidebar to copy the test key, which starts with creem_test_. Then fill in:

  • Test mode: on by default. No real money moves.
  • Live API key and Live webhook secret
  • Test API key and Test webhook secret

When you save, Stackless checks each new key with Creem, and a key in the other mode’s field gets an error. Moving a mode to a different Creem store clears the products remembered for that mode.

You can also set these as wp-config.php constants, which win over saved settings and hide their fields: STACKLESS_CREEM_LIVE_API_KEY, STACKLESS_CREEM_LIVE_WEBHOOK_SECRET, STACKLESS_CREEM_TEST_API_KEY and STACKLESS_CREEM_TEST_WEBHOOK_SECRET.

Connect the Webhook

On a public HTTPS site there’s nothing to do. Saving an API key creates a webhook named “Stackless for WooCommerce” in that Creem mode, subscribes it to the events below and saves its secret, with a notice such as “Creem test webhook connected and its secret saved.” A webhook already pointing at your URL is reused, and a secret you pasted yourself is never replaced.

A site that isn’t reachable over public HTTPS gets a notice instead. If Creem refuses, the error says why. Either way, add the webhook by hand: open Developers → Webhooks in Creem (switch on Test Mode first for the test endpoint), add https://yoursite.com/wp-json/stackless/v1/creem/webhook (the gateway settings show your exact URL), select these events and paste the secret into the field for the same mode:

checkout.completed
subscription.active
subscription.trialing
subscription.paid
subscription.update
subscription.scheduled_cancel
subscription.canceled
subscription.past_due
subscription.unpaid
subscription.paused
subscription.expired
refund.created
dispute.created

Creem signs each delivery with the creem-signature header, an HMAC-SHA256 of the raw body keyed with the webhook secret. Standard Webhooks headers are accepted too, within five minutes of their timestamp. The secret that matches decides whether the event is live or test, and each event is applied once. Webhooks confirm payments when a buyer closes the tab early, record renewals and failed renewals, and bring refunds, cancellations and disputes made in Creem into WooCommerce.

Set How Tax Works

  • Prices and tax: Add tax on top of my prices (the default) or My prices already include tax.
  • Tax category: Software as a service (the default), Digital goods or services, or E-books. Creem uses it to pick each buyer’s rate.

Turn off WooCommerce tax for products you sell through Creem, or buyers get taxed twice. With tax on top, the order total stays your price, and the payment note shows what Creem charged including tax. Changing either setting starts fresh Creem products.

What Buyers See

At checkout, Creem shows as “Card, Apple Pay or Google Pay (Creem)” with the description “You’ll finish paying on Creem’s secure checkout. Creem adds any sales tax or VAT for your location before you pay.” Test mode adds “Test mode: no real payment will be taken.” It works in the Checkout block, the classic checkout and the order payment page, so invoices can be paid through Creem too.

  • Placing the order sends the buyer to Creem’s checkout with their email filled in. Creem charges the order total, plus any tax it adds on top.
  • After paying, they come back to the order received page, and Stackless reads the checkout back from Creem before marking the order paid. An expired checkout sends them to the order payment page to try again.
  • If Creem reports a payment in another currency or for another amount, including one where a Creem discount code was used, the order goes on hold with a note to check it in Creem.

Products in Your Creem Catalog

Every Creem checkout sells a product from your Creem catalog. Stackless creates them on first use and remembers them for each mode, so there’s nothing to set on your WooCommerce products.

  • One-time sales use one Creem product per product or variation and currency, priced per checkout, so price changes, coupons and Pay What You Like amounts need no new product. Carts with several items share one product named “[Store name] order”.
  • Subscriptions use one product per product or variation, schedule, recurring amount and trial length, because Creem can’t set a subscription’s price or trial per checkout.
  • A product archived or deleted in Creem is created again on the next checkout.

Subscriptions on Creem

Creem runs the renewal schedule for subscriptions it bills:

  • Creem bills every 1 to 365 days, 1 to 52 weeks, 1 to 24 months or 1 to 3 years. A plan on any other schedule is refused at checkout.
  • Free trials work. Creem saves the card without charging, and the subscription shows as Trial until Creem’s first charge. The trial is passed to Creem in whole days.
  • Each renewal Creem charges becomes one paid WooCommerce renewal order. The next payment date follows Creem’s.
  • Creem’s past due, unpaid and paused show as On hold, canceled as Cancelled, expired as Expired, and a cancellation set for the end of the period as Pending cancellation.
  • After the last payment of a fixed-length plan, Stackless tells Creem to stop at the end of the period.

Cancelling from WooCommerce or My Account cancels at Creem too, at the end of the paid period or straight away. If Creem doesn’t confirm, the cancellation is refused with a message to try again or cancel at Creem.

Creem bills every subscription it takes, so the product’s Renewal mode can’t be Manual only. Checkout refuses that combination and asks the buyer to choose automatic renewal or another payment method.

When a Renewal Fails

Creem retries a failed card on its own schedule, and Stackless follows along with your retry settings:

  • When Creem reports the subscription past due, a renewal order is created and marked Failed, the subscription goes On hold, and the customer gets the Subscription payment failed email. Your retry schedule runs, but each retry only waits for Creem, which does the charging.
  • When one of Creem’s retries succeeds, that renewal order is paid and the subscription is Active again.
  • When Creem reports the subscription unpaid, its own retries have run out. If the renewal is still unpaid when your retry period ends, the subscription is cancelled here and at Creem.
  • A failed Creem renewal can’t be paid from the store, so nobody is charged twice. The order payment page points the customer to their subscription instead. Customers update their card in Creem’s customer portal, linked in Creem’s receipts.

Refunds and Disputes

  • Refunds from the WooCommerce order screen refund the whole Creem payment. A partial amount is refused with a message to refund the full total or use the Creem dashboard. Refund a renewal from its own renewal order.
  • Refunds made in the Creem dashboard, partial or full, are recorded on the order once, scaled back to the pre-tax amount when Creem added tax on top. Items aren’t restocked.
  • Disputes opened in Creem add an order note.

More Than One Creem Store

Creem can be duplicated for a second Creem store, each copy with its own keys, products, orders and webhook URL ending in /webhook/copy2 and so on. Saving a copy’s key creates its webhook in that store the same way. Constants in wp-config.php apply to the original only. See Duplicate a Payment Gateway.

Check the Connection

  • Billing Health lists Creem setup problems for the original and every copy: no API key for the current mode, a key for the other mode, a missing webhook secret, no webhook received yet, and test mode left on. It also shows recent webhook events that failed.
  • Turn on Debug log to write Creem activity to WooCommerce → Status → Logs (stackless-creem_gateway). Keys are never logged.

Limits

  • Creem charges in US dollars and euros only, from 1.00, and isn’t offered for other currencies. It works with Multi-Currency Checkout, and Currency-Aware Payment Gateways knows its list.
  • Creem takes one subscription per checkout, with no other items in the cart, and isn’t offered for carts it can’t take. One-time carts can be any size.
  • Creem bills the same amount every cycle, so a subscription with a signup fee or a different first payment is refused at checkout.
  • Creem doesn’t save cards in WooCommerce. Customers can’t renew early, resume a pending cancellation, toggle auto-renew, change the payment method, switch plans, pause or skip a renewal from My Account, and you can’t change the next payment date. A subscription paused in the Creem dashboard shows as On hold.
  • If your retry schedule ends before Creem’s own retries do, the subscription is cancelled at Creem when your schedule ends.

For Developers

Filters: stackless_creem_gateway_checkout_args (the checkout sent to Creem), stackless_creem_gateway_product_args (a product before it’s created) and stackless_creem_gateway_currencies (can narrow the list to USD or EUR). Actions: stackless_creem_gateway_webhook after each applied event, and stackless_creem_gateway_subscription_synced when Creem changes a subscription’s status:

add_action('stackless_creem_gateway_webhook', function ($type, $object, $mode, $gateway_id) {
    if ($type === 'dispute.created') {
        error_log('Creem dispute for ' . $gateway_id . ' in ' . $mode . ' mode');
    }
}, 10, 4);

Override the checkout fields by copying the template to yourtheme/stackless/creem_gateway/payment-fields.php.

Share

Was this helpful?

Still stuck? Open a support ticket