LogoMkSaaS ドキュメント
LogoMkSaaS ドキュメント
ホームページIntroductionCodebaseVideo TutorialsGetting StartedEnvironment Setup
Configuration

Integrations

DatabaseAuthenticationEmailNewsletterStorage
Payment
StripeCreemWaffo Pancake
AIAnalyticsNotificationCaptchaChatboxAffiliates

Customization

MetadataFontsThemesImagesi18nBlogDocsComponentsCustom PagesLanding PageUser ManagementAPI Key Management

Codebase

IDE SetupProject StructureFormatting & LintingUpdating the Codebase
X (Twitter)
Payment

Waffo Pancake

How to set up and use Waffo Pancake for payments and subscriptions

MkSaaS supports Waffo Pancake for one-time payments and subscriptions. Waffo is a Merchant of Record (MoR), so it handles global tax calculation, collection, compliance, and payouts on your behalf.

The integration uses the official @waffo/pancake-ts SDK together with Waffo's hosted checkout and consumer portal. Card details do not pass through your application server.

Setup

MkSaaS includes a free plan, a Pro subscription plan with monthly and yearly intervals, and a Lifetime one-time plan by default.

Create a Waffo Account

Sign up at pancake.waffo.ai and create a store during onboarding. The Waffo Quickstart explains the basic account setup.

Get API Credentials

In Waffo Dashboard, open API & Development and click Create API Key. Copy the Merchant ID and private key, then save them as WAFFO_MERCHANT_ID and WAFFO_PRIVATE_KEY.

WAFFO_MERCHANT_ID is the Merchant ID, not a storeId or a store identifier copied from a URL. API keys are bound to the test or production environment when they are created, so create a separate key for each environment.

The private key is server-only. Preserve PEM line breaks with escaped \n characters when storing it in an environment variable:

WAFFO_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEv...\n-----END PRIVATE KEY-----"

Configure the Webhook

In Waffo Dashboard > Settings > Webhooks, click Add Webhook and configure:

  • Payload format: Raw. This format includes the X-Waffo-Signature header required for verification.
  • URL: https://YOUR-DOMAIN.com/api/webhooks/waffo
  • Events: keep the payment, subscription, and refund events listed in the Webhook Events section.

Waffo does not require a webhook secret environment variable. The @waffo/pancake-ts SDK contains the verification keys and verifies the raw request body with verifyWebhook().

Create Products

Waffo checkout uses Product IDs beginning with PROD_, rather than Stripe-style price IDs:

  • Create a monthly Subscription product and save its ID as NEXT_PUBLIC_WAFFO_PRODUCT_PRO_MONTHLY.
  • Create a yearly Subscription product and save its ID as NEXT_PUBLIC_WAFFO_PRODUCT_PRO_YEARLY.
  • Create a One-time product and save its ID as NEXT_PUBLIC_WAFFO_PRODUCT_LIFETIME. New products start in test mode. Publish them to production before accepting real payments; publishing is a one-way operation. See the Waffo subscriptions guide and Publish Product.

Add Environment Variables

Set the provider and Waffo credentials in .env:

.env
NEXT_PUBLIC_PAYMENT_PROVIDER=waffo

# Server-side credentials
WAFFO_MERCHANT_ID=MER_...
WAFFO_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEv...\n-----END PRIVATE KEY-----"

# Optional: accept sandbox webhooks in a production build for smoke tests
# WAFFO_DEBUG=true

# Product IDs
NEXT_PUBLIC_WAFFO_PRODUCT_PRO_MONTHLY=PROD_...
NEXT_PUBLIC_WAFFO_PRODUCT_PRO_YEARLY=PROD_...
NEXT_PUBLIC_WAFFO_PRODUCT_LIFETIME=PROD_...

Configure Pricing

Keep the existing price.plans configuration in src/config/website.tsx, but make its priceId values resolve to the Waffo product IDs when Waffo is active. The amount, currency, interval, and plan metadata must match the products configured in Waffo.

src/config/website.tsx
price: {
  plans: {
    pro: {
      id: 'pro',
      prices: [
        {
          type: PaymentTypes.SUBSCRIPTION,
          priceId: process.env.NEXT_PUBLIC_WAFFO_PRODUCT_PRO_MONTHLY!,
          amount: 990,
          currency: 'USD',
          interval: PlanIntervals.MONTH,
        },
        {
          type: PaymentTypes.SUBSCRIPTION,
          priceId: process.env.NEXT_PUBLIC_WAFFO_PRODUCT_PRO_YEARLY!,
          amount: 9900,
          currency: 'USD',
          interval: PlanIntervals.YEAR,
        },
      ],
      isFree: false,
      isLifetime: false,
    },
  },
},

Core Features

  • Monthly and yearly recurring subscriptions
  • Lifetime one-time payments
  • Hosted checkout without handling card data on your server
  • Webhook handling for payments, subscriptions, and refunds
  • Waffo-managed tax, compliance, and payouts
  • Shared consumer portal with Magic Link login
  • Provider-agnostic pricing, checkout, and billing components

Development

Waffo must be able to reach your webhook endpoint during local development. Expose the local server through an HTTPS tunnel:

ngrok http 3000
# or
cloudflared tunnel --url http://localhost:3000

Register the tunnel URL as a test webhook, for example https://xxxx.ngrok-free.app/api/webhooks/waffo. Do not put a temporary tunnel URL in the production webhook. Avoid localtunnel because it can strip the X-Waffo-Signature header.

The template includes a Waffo sandbox E2E suite:

pnpm e2e:waffo

The sandbox checkout does not create real charges. Choose Credit/Debit Card and use the Quick Fill Success option, or use one of the test cards listed below. The ignored MkFast Template environment file can be reused by setting WAFFO_ENV_FILE when running the local E2E helper.

Production

  1. Complete Waffo store review / KYB so production payments are enabled.
  2. Publish the subscription and one-time products from test to production.
  3. Create production API credentials and set WAFFO_MERCHANT_ID and WAFFO_PRIVATE_KEY to those credentials.
  4. Register https://YOUR-DOMAIN.com/api/webhooks/waffo as the production webhook.
  5. Leave WAFFO_DEBUG unset or set it to false. Sandbox events must never grant access in a production build.

Customer Portal

Waffo provides the shared consumer portal at https://pancake.waffo.ai/consumer/portal/login. Customers sign in with the email used for their purchase and a one-time Magic Link. They can view subscriptions and invoices, cancel or reactivate subscriptions, update billing details, and request refunds.

Webhook Events

Configure the following events for /api/webhooks/waffo:

EventDescription
order.completedOne-time order payment succeeded
subscription.activatedSubscription first payment succeeded
subscription.payment_succeededRenewal payment succeeded
subscription.updatedSubscription product changed
subscription.cancelingCancellation requested; active until period end
subscription.uncanceledCancellation withdrawn
subscription.canceledSubscription terminated
subscription.past_dueRenewal payment failed and is being retried
refund.succeededRefund completed and access is revoked
refund.failedRefund failed

Waffo sends test and production events to the same endpoint and includes a mode field in every payload. MkSaaS rejects events whose mode does not match the running environment.

Test Cards

Use Waffo test mode with any future expiry date and any three-digit CVC:

CardTypeResult
4576 7500 0000 0110Visa CreditSuccess
2226 9000 0000 0110Mastercard CreditSuccess
4576 7500 0000 0220Visa CreditDeclined

Best Practices

  1. Keep WAFFO_PRIVATE_KEY and WAFFO_MERCHANT_ID on the server only.
  2. Use the Raw webhook format so X-Waffo-Signature is preserved.
  3. Use test and production credentials in their matching environments.
  4. Complete a full sandbox checkout and webhook round trip before going live.

References

  • Waffo Pancake Documentation
  • Waffo Quickstart
  • API Key Authentication
  • TypeScript SDK
  • Webhooks Guide
  • Test Mode
  • Customer Portal

Creem

How to set up and use Creem for payments and subscriptions

AI

Learn how to set up and use AI features

目次

SetupCreate a Waffo AccountGet API CredentialsConfigure the WebhookCreate ProductsAdd Environment VariablesConfigure PricingCore FeaturesDevelopmentProductionCustomer PortalWebhook EventsTest CardsBest PracticesReferences