Skip to main content
Copy this prompt to your AI code editor (Cursor, Copilot, etc.) to create checkout integration:

What You’ll Build

A checkout session is a dynamically generated payment page. Instead of sharing a static product link, you can:
  • Pre-fill customer email
  • Track orders with custom metadata
  • Set custom success URLs
  • Enable trial periods for subscriptions
  • Tailor language and payment methods to your audience

Prerequisites

  • Waffo Pancake account
  • API key (Dashboard → API & Development)
  • At least one product created

Basic Checkout Session

The simplest checkout session needs a product ID and currency.

Using REST API Directly

Response:
Redirect your customer to checkoutUrl to complete payment.

Redirect Best Practices

Do not use window.open() to open the checkout page. Safari and many mobile browsers block popup windows opened from asynchronous callbacks (e.g., after an API call). This causes checkout to silently fail for your customers.
Recommended approaches:
After payment, the customer is redirected back to your successUrl. The successUrl is used as-is and no placeholders are replaced; to identify the purchase on your success page, add your own identifier (such as your internal order ID) to the successUrl query string before creating the session, and rely on webhooks to confirm the payment.

Pre-fill Customer Email

Skip the email input step by pre-filling it:
Use case: User is already logged into your app, so you know their email.

Tailor Checkout to Your Audience

Out of the box the hosted checkout is tuned for a global audience: it offers every payment method the currency supports, opens in the shopper’s browser language, and leaves the form blank. That is the right default when you sell everywhere. When most of your buyers come from one market, narrow it — a shopper who sees only the wallet they use every day, in their own language, with their email already filled in, is far less likely to hesitate or abandon. Four parameters on the checkout session control this. All of them are optional and independent:

Recipe

  1. Price in the currency your buyers pay in. The currency, not the buyer’s location, decides which methods the checkout can offer. Check the support table before you pick.
  2. Set language to the buyer’s locale. Skip it if your buyers are spread across markets — browser detection already handles that.
  3. Narrow payment methods to what the market uses. For a single market use includePaymentMethods and list only what buyers there recognize. For several markets prefer excludePaymentMethods — values a currency does not offer are ignored, so one blacklist works across currencies.
  4. Pre-fill buyerEmail whenever the buyer is logged in. Your buyer already has an account with you; asking for an email again invites hesitation (“do I use the same one?”). In authenticated checkout pass buyerIdentity and buyerEmail together.
  5. Leave billingDetail out unless you need tax pre-fill. Passing it locks the checkout to that country’s payment market and the buyer cannot switch.

Examples

Mainland China

Buyers pay with WeChat Pay and read Simplified Chinese. WeChat Pay is available for one-time products priced in CNY or USD, up to about ¥1,000 (≈ $140) per order.
Subscriptions cannot use WeChat Pay, so for a subscription product drop includePaymentMethods and let the buyer pay by card.

Japan

Buyers expect JPY pricing and a Japanese UI. Cards and wallets all support JPY, so there is nothing to narrow — set the currency and language and keep the default methods.

Multiple markets

Pick the configuration per buyer at request time from a signal you already have — the account’s country, the UI locale, or the plan they chose. Anything you cannot infer, leave out and let the checkout fall back to its defaults.
Payment method filters need API Key authentication. includePaymentMethods and excludePaymentMethods are silently ignored on Store Slug sessions and on link-mode buttons — which method to offer is a merchant-side decision (fees, settlement), so it can only be made server-side. language and buyerEmail work in both modes.
Every value in includePaymentMethods must be supported by the product type × currency you send, or the request fails with 400 Payment methods not supported. A method can also be hidden at checkout for a single order — for example WeChat Pay above its per-order limit — so when you whitelist one method, make sure your prices stay inside its limits.

Track with Metadata

Link checkout sessions to your internal systems:
Metadata is stored on the checkout session and is passed back in the orderMetadata field of webhook payloads. Merchant credentials (API Key) cannot query checkoutSession through GraphQL.

Subscription with Trial

Enable a trial period for subscription products:
Per-seat quantities are not yet supported via the API. For one-time products, new subscriptions and plan changes, pass couponId to apply a coupon, promotionCode to pre-fill a code, or allowPromotionCodes: true to show a code entry field — see Discounts & Promotions.

Subscription with Billing Detail

Pre-fill the consumer’s billing information for tax calculation:

Dynamic Success URL

Pass data to your success page:
The redirect goes to successUrl as-is — placeholders such as {SESSION_ID} are not replaced. Build the identifiers you need into the URL yourself, and rely on webhooks to confirm the payment.

Complete Example: SaaS Upgrade Flow

Here’s a real-world example for upgrading a user’s subscription using the SDK:
If you need to handle checkout on the client side (e.g., SPA):

Parameters Reference


Next Steps

Handle Webhooks

Get notified when payments complete

Verify Payments

Securely verify webhook signatures