Creem
Creem checkout and webhook provider for the Nuxt template.
Creem is the default provider. It implements the
PaymentProvider interface in
server/payment/providers/creem-provider.ts and is registered by the factory
when NUXT_CREEM_API_KEY is set.
Configuration
| Variable | Purpose |
|---|---|
NUXT_PUBLIC_PAYMENT_PROVIDER | Set to creem (the default) to select this provider. |
NUXT_CREEM_API_KEY | Server key for creating checkouts (also gates registration). |
NUXT_CREEM_SERVER_IDX | Selects the Creem server: 0 = production, 1 = test. |
NUXT_CREEM_WEBHOOK_SECRET | HMAC secret for verifying webhook signatures. |
NUXT_PUBLIC_CREEM_PRODUCT_PRO_MONTHLY / _PRO_YEARLY / _LIFETIME | Public Creem product IDs for the three plans. |
Checkout
createPayment builds a Creem checkout for the requested productId and returns
{ orderNo, thirdOrderNo, checkoutUrl }. The create route redirects the browser
to checkoutUrl, which returns to /pay-success?orderId=<orderNo>.
Webhook
- Path:
POST /api/payment/notify/creem. - Signature: HMAC-SHA256 of the raw body using
NUXT_CREEM_WEBHOOK_SECRET, compared to thecreem-signatureheader. An invalid signature returns401. - Handled events:
checkout.completed— marks the matchingpaymentrowsuccess.- Subscription lifecycle —
subscription.active,subscription.paid,subscription.update,subscription.trialing,subscription.paused,subscription.past_due,subscription.scheduled_cancel,subscription.canceled, andsubscription.expiredupsert the user'ssubscriptionrow to the matching status, period, and cancel timestamps. refund.created— marks the matchingpaymentrowrefunded.
Local testing
- Use the Creem test server (
NUXT_CREEM_SERVER_IDX=1) and test product IDs. - Expose your local webhook with a tunnel and register
https://<tunnel>/api/payment/notify/creemin Creem. - A valid signature flips the order to
success; an invalid one returns401.
Production notes
- Set production product IDs and
NUXT_CREEM_SERVER_IDX=0. - Add idempotency — webhooks can be delivered more than once.
- Verify amounts server-side against your catalog before charging real users.
Verify
- A logged-in user can start checkout from the pricing page; a
paymentrow is created. -
GET /api/payment/query?orderId=…returns the order status. - A Creem webhook with a valid signature flips the order to
success. - Guest (logged-out) checkout returns
401, not500.
