WaffoStripe.client(...), add the routing marker and handoff time to the target subscription, and connect the Waffo Webhook. Your existing com.stripe.* types and calling pattern stay in place. Quick start shows the complete code change; before production, also persist the idempotency key and subscription mapping described in the integration guide.
The migration tool is available for Java today:
com.waffo:waffo-java-stripe. Node.js, Python, and Go versions are coming soon.This is not the native Waffo SDK
Waffo offers two entirely different integration paths. Confirm which one fits you before going further.
For a new integration, use the native SDK. The adapter earns its place in exactly one situation: you already run subscriptions on Stripe and the cost of changing that code is your main concern.
What the migration tool does for you
Routing
Decides per request whether it goes to Waffo or straight to Stripe, so your calling code needs no branching.
Parameter translation
Turns Stripe’s
SessionCreateParams into a Waffo subscription request — amount, period, currency, payment method, cashier language.Response mapping
Packs Waffo’s response back into Stripe
Session and Subscription objects, so your usual getters keep working.Notification translation
Translates Waffo subscription notifications into Stripe
Events, so your existing Webhook branches still apply.How it works
The adapter hands you a standardStripeClient. It inspects each request and applies three rules:
In other words, untagged calls are completely unaffected — one-time payments, untagged subscriptions, customer objects, price objects all behave exactly as they did before. You can move a subset of subscriptions to Waffo and run both sides in parallel.
A complete subscription payment flows like this:
1
Create the subscription Checkout
You call
client.checkout().sessions().create(params) as usual; params just carries one more line, metadata.source=waffo. The adapter translates it into a Waffo subscription request.2
Receive the cashier URL
You still get a Stripe
Session object, and session.getUrl() holds the Waffo cashier URL. Your redirect code needs no change — it never cared where that URL pointed.3
The customer pays
The customer completes payment on the Waffo cashier. Your application is not involved in this leg.
4
Receive and translate the notification
Waffo posts the subscription notification to your configured
notifyUrl. Your endpoint calls WaffoStripeWebhooks.handle(...) and gets a WaffoStripeWebhookResult; call result.getEvent() to obtain the standard Stripe Event.5
Existing business logic runs
Your existing
switch (event.getType()) handling for customer.subscription.created and invoice.paid needs no change; it receives the translated event directly.What is supported
The first phase targets hosted-cashier subscriptions. Use the table below to judge whether your current setup fits.
For the complete fallback conditions, reason codes, and cancellation boundaries, see unsupported Stripe usage in the integration guide.
Move expiring Stripe subscriptions to Waffo
Suppose the current paid period of a Stripe subscription ends at timeT. Use your existing Stripe flow to stop renewal at T, then create a Waffo subscription for the same customer that starts at T:
1
Read the handoff time
Read the paid-through period end
T from the Stripe subscription.2
Set the Waffo start time
Set
subscription_data.billing_cycle_anchor to T on the Waffo-routed request and set proration_behavior=none.3
Authorize in advance
Before
T, the customer opens the Waffo cashier and completes card entry and any required 3DS challenge. No first charge is collected yet.4
Confirm the waiting state
While waiting, retrieve the
wsub_… subscription. Both billing_cycle_anchor and current_period_end equal T; metadata.waffo_current_period=0 means period 1 has not started.5
Charge automatically at handoff
At
T, Waffo initiates the first charge automatically. The customer does not need to return.T, Subscription.cancel("wsub_…") immediately cancels the Waffo subscription and prevents the scheduled first charge.
The Stripe migration tool manages the Waffo-side application, inquiry, and cancellation. It does not modify the original Stripe subscription. Use your existing Stripe code or dashboard to end the old subscription at the same
T.Quick start
The following three steps show the key code changes. In addition to those changes, persist the idempotency key before sending the request and store the relationship between the Waffo subscription id and your business order after creation. These are partial snippets for an existing class and assume your project’s surrounding imports, injected fields, and business methods.Step 1 — Swap the client constructor
client you get back is a standard StripeClient. Drop it in where your old one was; every call site stays untouched.
Step 2 — Add the routing tag and idempotency key
uiMode. Stripe defaults to a hosted Checkout, and the migration tool also treats an omitted value as hosted. This keeps the code compatible with stripe-java 24.11.x, 32.x, and 33.x. Do not substitute HOSTED_PAGE on 32.x or 33.x: its serialized hosted_page value is classified as a non-hosted Checkout.
Do not rely on an idempotency key generated automatically by stripe-java. Explicitly pass and persist a stable key of at most 32 characters, and reuse it on every retry. See the integration guide for the full rules.
Step 3 — Integrate the Waffo Webhook
Your application still needs a new HTTP endpoint, while your existing Stripe Webhook endpoint stays unchanged. The SDK’shandle(...) method already verifies and parses the notification, translates its event, and generates the acknowledgment response. Your endpoint only passes the translated result to your business code and maps the SDK-generated acknowledgment into your Web framework’s response.
WaffoStripeWebhookResult already contains the acknowledgment body. The final lines only map it into Spring’s ResponseEntity; use the equivalent mapping for another Web framework. See the integration guide.
Integration guide
The full configuration reference, Webhook handling details, the complete unsupported-usage table, the integration checklist, and Sandbox verification requirements.
Migrate automatically with the AI skill
If you work in Claude Code, Codex, or Cursor, you can let the assistant handle the scan and the rewrite:Scan results only surface risk; they are not an acceptance conclusion. Whichever path you take, the integration is complete only after the full Sandbox flow passes through your own project’s endpoints. See Sandbox verification.
Version and prerequisites
stripe-java is a provided dependency, meaning the adapter will not upgrade or downgrade it for you—the version already in your project stays put. Make sure it is version 24.11.0 or later.
Before integrating, also confirm:
- You have a subscription agreement with Waffo and hold Sandbox credentials
- The currencies you plan to route are within your contract; verify with
paymethodconfig/inquiry - You have a publicly reachable HTTPS endpoint for Waffo notifications
Related resources
- Integration guide — full steps and technical details
- Waffo Java SDK — the native SDK, recommended for new integrations
- Subscription and recurring payments — Waffo subscription capabilities
- GitHub repository — source and changelog