PLAYGROUND connected · test-mode
Fork on GitHub
PREVIEW route · ch-inline flow · payment-intent
S stitch example app
← Back to plans
UPGRADING TO

Pro plan

For small teams

Pro · monthly
Renews monthly · cancel anytime
CHF 27.00
SubtotalCHF 27.00
VAT / Taxcalculated at confirmation
Total today CHF 27.00
    route · ch-inline

    How would you like to pay?

    you@stitch.example
    4242 4242 4242 4242 V M
    MM / YY
    CVC

    Powered by stripe via tenderlane · By paying, you agree to the Terms.

    RULES · routing.ts
    first-match-wins · 5 rules · 1 fallback
    #1 ch-inline matched
    when {'country':'CH','currency':'chf'} use {'provider':'stripe','flow':'payment-intent','paymentMethods':['card','twint']}
    #2 nl-ideal matched
    when {'country':'NL','currency':'eur'} use {'provider':'stripe','flow':'payment-intent','paymentMethods':['card','ideal','sepa']}
    #3 de-klarna matched
    when {'country':'DE','currency':'eur'} use {'provider':'stripe','flow':'payment-intent','paymentMethods':['card','sepa','klarna']}
    #4 br-pix matched
    when {'country':'BR','currency':'brl'} use {'provider':'stripe','flow':'payment-intent','paymentMethods':['card','pix']}
    #5 gb-card matched
    when {'country':'GB','currency':'gbp'} use {'provider':'stripe','flow':'payment-intent','paymentMethods':['card']}
    fallback matched
    {'provider':'stripe','flow':'checkout-session','paymentMethods':['card']}
    CONTEXT · the inputs your rules read
    country
    currency
    plan
    user.tier
    flags
    inline-checkout · ramp 64%
    3ds-always · ramp 100%
    localized-receipts · ramp 12%
    RESOLVED CONTEXT
     
    EVENT STREAM
    onRouteEvaluated · onStateChange
    context routing state adapter
    SOURCE · the code that wires this playground
    import { TenderlaneProvider,
             TenderlaneCheckoutForm } from 'tenderlane/react';
    import { createRulesRouter }       from 'tenderlane';
    import { stripeProvider }          from 'tenderlane/stripe';
    import { StripePaymentElement }    from 'tenderlane/stripe/react';
    
    import { rules, fallback } from './routing';
    import { useAppContext }   from './context';
    
    const stripe = stripeProvider({
      publishableKey: env.STRIPE_PK,
      serverEndpoint: '/api/pay',
    });
    
    export function Checkout({ plan }) {
      const ctx = useAppContext();   // country, currency, tier, flags
    
      return (
        <TenderlaneProvider config={{
          context: ctx,
          providers: [stripe],
          routing: createRulesRouter({ rules, fallback }),
        }}>
          <OrderSummary plan={plan} />
          <TenderlaneCheckoutForm
            input={{ amount: plan.amount[ctx.currency], currency: ctx.currency }}
            elements={{ stripe: StripePaymentElement }}
          >
            {({ canSubmit, submit, status }) => (
              <button disabled={!canSubmit} onClick={submit}>
                {status === 'submitting' ? 'Processing…' : 'Pay'}
              </button>
            )}
          </TenderlaneCheckoutForm>
        </TenderlaneProvider>
      );
    }