SeaEsta is in preview. Listings shown are demonstrations; bookings open soon. No booking payment can be taken on this site today.
← Back to Sea-Esta
GatewayStripe live · PayPal staged

Payment Flow Launchpad

Flows built here can run locally (Stripe) or be exported to the NoblePort Payment Gateway (Stripe + PayPal) that serves all NoblePort dapps. Direct mode uses this app's own live Stripe integration; Gateway mode produces a deployment package — a JSON flow definition plus a client snippet that calls POST https://gateway.nobleport.app/v1/checkout.

Where this flow runs

Gateway target

Gateway mode: nothing executes here. The builder emits a deployment package for the central NoblePort Payment Gateway.

Stripe / PayPal / Both

Processor

Stripe · LivePayPal · Staged

Staged — connect PayPal credentials in the NoblePort Payment Gateway. PayPal is generated as exportable configuration only — order create + capture for one-time payments, a billing plan for subscriptions, and a partial capture with balance due for deposits. No PayPal transaction is executed by this app.

Definition

Flow configuration

Flow type
Additional currencies

Each currency exports its own amount. Stripe gets currency_options; PayPal gets one order/plan per currency. Leave an amount blank to reuse the base amount.

Export to NoblePort

Deployment package

Charge now
499.00 USD · 459.00 EUR
Type
Subscription
Processor
Both
Warnings
  • additionalCurrencies PayPal cannot mix currencies in one plan — the export generates one per currency.

Copy or download the JSON definition and the client snippet below, then deploy them to the NoblePort Payment Gateway. The gateway holds the Stripe and PayPal credentials for every NoblePort dapp.

nobleport.payment_flow

Flow definition (JSON)

schema v1.3.0builder v1.3.0templates v1.1.0released 2026-08-01
Schema changelog (embedded in every export)
  • v1.3.0 · 2026-08-01
    • Added `schema` block with schema/builder versions, changelog and template provenance.
  • v1.2.0 · 2026-07-01
    • Added multi-currency `pricing[]` with per-currency minor units and PayPal support flags.
    • Stripe exports use `currency_options`; PayPal exports one order/plan per currency.
  • v1.1.0 · 2026-06-01
    • Added `webhooks` configuration block and signed handler snippet generation.
  • v1.0.0 · 2026-05-01
    • Initial payment_flow document: one-time, subscription and deposit flows.
{
  "version": "1.0",
  "kind": "nobleport.payment_flow",
  "id": "flow_sea_esta_host_membership",
  "name": "Host Membership",
  "type": "subscription",
  "processor": "both",
  "target": "gateway",
  "amount": {
    "value": 499,
    "minor_units": 49900,
    "currency": "USD"
  },
  "charge_now": {
    "value": 499,
    "minor_units": 49900,
    "currency": "USD"
  },
  "currencies": [
    "USD",
    "EUR"
  ],
  "pricing": [
    {
      "currency": "USD",
      "decimals": 2,
      "amount": {
        "value": 499,
        "minor_units": 49900,
        "display": "499.00 USD"
      },
      "charge_now": {
        "value": 499,
        "minor_units": 49900,
        "display": "499.00 USD"
      },
      "paypal_supported": true
    },
    {
      "currency": "EUR",
      "decimals": 2,
      "amount": {
        "value": 459,
        "minor_units": 45900,
        "display": "459.00 EUR"
      },
      "charge_now": {
        "value": 459,
        "minor_units": 45900,
        "display": "459.00 EUR"
      },
      "paypal_supported": true
    }
  ],
  "schedule": {
    "interval": "year",
    "interval_count": 1
  },
  "urls": {
    "success_url": "https://seaesta.lovable.app/checkout/return",
    "cancel_url": "https://seaesta.lovable.app/"
  },
  "metadata": {
    "product": "host_membership",
    "dapp": "Sea-Esta",
    "platform": "NoblePort",
    "currencies": "USD,EUR"
  },
  "processors": {
    "stripe": {
      "mode": "subscription",
      "ui_mode": "embedded_page",
      "currency": "usd",
      "currencies": [
        "USD",
        "EUR"
      ],
      "line_items": [
        {
          "quantity": 1,
          "price_data": {
            "currency": "usd",
            "unit_amount": 49900,
            "product_data": {
              "name": "Host Membership"
            },
            "recurring": {
              "interval": "year"
            },
            "currency_options": {
              "eur": {
                "unit_amount": 45900
              }
            }
          }
        }
      ],
      "return_url": "https://seaesta.lovable.app/checkout/return",
      "cancel_url": "https://seaesta.lovable.app/",
      "metadata": {
        "product": "host_membership",
        "dapp": "Sea-Esta",
        "platform": "NoblePort",
        "flow_type": "subscription",
        "currencies": "USD,EUR"
      },
      "execution": "live"
    },
    "paypal": {
      "intent": "SUBSCRIPTION",
      "execution": "staged",
      "execution_note": "Staged — connect PayPal credentials in the NoblePort Payment Gateway",
      "currencies": [
        "USD",
        "EUR"
      ],
      "plan": {
        "product_id": "PROD-HOST_MEMBERSHIP",
        "name": "Host Membership (USD)",
        "status": "ACTIVE",
        "billing_cycles": [
          {
            "frequency": {
              "interval_unit": "YEAR",
              "interval_count": 1
            },
            "tenure_type": "REGULAR",
            "sequence": 1,
            "total_cycles": 0,
            "pricing_scheme": {
              "fixed_price": {
                "value": "499.00",
                "currency_code": "USD"
              }
            }
          }
        ],
        "payment_preferences": {
          "auto_bill_outstanding": true,
          "setup_fee_failure_action": "CANCEL",
          "payment_failure_threshold": 2
        }
      },
      "by_currency": {
        "USD": {
          "product_id": "PROD-HOST_MEMBERSHIP",
          "name": "Host Membership (USD)",
          "status": "ACTIVE",
          "billing_cycles": [
            {
              "frequency": {
                "interval_unit": "YEAR",
                "interval_count": 1
              },
              "tenure_type": "REGULAR",
              "sequence": 1,
              "total_cycles": 0,
              "pricing_scheme": {
                "fixed_price": {
                  "value": "499.00",
                  "currency_code": "USD"
                }
              }
            }
          ],
          "payment_preferences": {
            "auto_bill_outstanding": true,
            "setup_fee_failure_action": "CANCEL",
            "payment_failure_threshold": 2
          }
        },
        "EUR": {
          "product_id": "PROD-HOST_MEMBERSHIP",
          "name": "Host Membership (EUR)",
          "status": "ACTIVE",
          "billing_cycles": [
            {
              "frequency": {
                "interval_unit": "YEAR",
                "interval_count": 1
              },
              "tenure_type": "REGULAR",
              "sequence": 1,
              "total_cycles": 0,
              "pricing_scheme": {
                "fixed_price": {
                  "value": "459.00",
                  "currency_code": "EUR"
                }
              }
            }
          ],
          "payment_preferences": {
            "auto_bill_outstanding": true,
            "setup_fee_failure_action": "CANCEL",
            "payment_failure_threshold": 2
          }
        }
      },
      "application_context": {
        "brand_name": "Sea-Esta",
        "user_action": "SUBSCRIBE_NOW",
        "return_url": "https://seaesta.lovable.app/checkout/return",
        "cancel_url": "https://seaesta.lovable.app/"
      }
    }
  },
  "webhooks": {
    "endpoint": "https://seaesta.lovable.app/api/public/gateway/events",
    "events": [
      "checkout.completed",
      "checkout.failed",
      "checkout.canceled",
      "subscription.activated",
      "subscription.renewed",
      "subscription.canceled",
      "payment.refunded"
    ],
    "signature": {
      "algorithm": "hmac-sha256",
      "header": "x-nobleport-signature",
      "timestamp_header": "x-nobleport-timestamp",
      "signed_payload": "{timestamp}.{raw_body}",
      "tolerance_seconds": 300,
      "secret_name": "NOBLEPORT_GATEWAY_WEBHOOK_SECRET"
    },
    "retry": {
      "max_attempts": 5,
      "backoff": "exponential"
    },
    "idempotency": {
      "key": "event_id",
      "scope": "flow"
    },
    "handling": "ui_status_only",
    "note": "Staged — the gateway endpoint only records events and updates flow UI status. It never touches Stripe billing state, which stays owned by the existing Stripe webhook."
  },
  "generated_at": "1970-01-01T00:00:00.000Z",
  "schema": {
    "schema_version": "1.3.0",
    "builder_version": "1.3.0",
    "kind_version": "1.0",
    "released_at": "2026-08-01",
    "source": "gateway_launchpad",
    "changelog": [
      {
        "version": "1.3.0",
        "date": "2026-08-01",
        "changes": [
          "Added `schema` block with schema/builder versions, changelog and template provenance."
        ]
      },
      {
        "version": "1.2.0",
        "date": "2026-07-01",
        "changes": [
          "Added multi-currency `pricing[]` with per-currency minor units and PayPal support flags.",
          "Stripe exports use `currency_options`; PayPal exports one order/plan per currency."
        ]
      },
      {
        "version": "1.1.0",
        "date": "2026-06-01",
        "changes": [
          "Added `webhooks` configuration block and signed handler snippet generation."
        ]
      },
      {
        "version": "1.0.0",
        "date": "2026-05-01",
        "changes": [
          "Initial payment_flow document: one-time, subscription and deposit flows."
        ]
      }
    ]
  }
}
POST /v1/checkout

Gateway API snippet

// Sea-Esta → NoblePort Payment Gateway
// POST https://gateway.nobleport.app/v1/checkout with your app API key.
// Flow: flow_sea_esta_host_membership (Subscription, Both)
// Currencies: USD, EUR
// Schema 1.3.0 · builder 1.3.0 · generated 1970-01-01T00:00:00.000Z


const GATEWAY_URL = "https://gateway.nobleport.app/v1/checkout";
const APP_API_KEY = process.env.NOBLEPORT_APP_API_KEY!; // server-side only

// Charge-now amounts in minor units, per presentment currency.
export const PRICES = {
  USD: { amount: 49900, currency: "USD" },
  EUR: { amount: 45900, currency: "EUR" },
} as const;

export type FlowCurrency = keyof typeof PRICES;
export const DEFAULT_CURRENCY: FlowCurrency = "USD";

export async function startCheckout(
  opts: { customerEmail?: string; processor?: "stripe" | "paypal"; currency?: FlowCurrency } = {},
) {
  const price = PRICES[opts.currency ?? DEFAULT_CURRENCY];
  if (!price) throw new Error(`Unsupported currency: ${opts.currency}`);

  const res = await fetch(GATEWAY_URL, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${APP_API_KEY}`,
      "X-NoblePort-Dapp": "Sea-Esta",
    },
    body: JSON.stringify({
      flow_id: "flow_sea_esta_host_membership",
      processor: opts.processor ?? "stripe",
      amount: price.amount,        // minor units for the selected currency
      currency: price.currency,
      type: "subscription",
      schedule: { interval: "year", interval_count: 1 },
      success_url: "https://seaesta.lovable.app/checkout/return",
      cancel_url: "https://seaesta.lovable.app/",
      customer_email: opts.customerEmail,
      metadata: {"product":"host_membership","dapp":"Sea-Esta","platform":"NoblePort","currencies":"USD,EUR"},
    }),
  });


  if (!res.ok) throw new Error(`Gateway error ${res.status}: ${await res.text()}`);

  // { checkout_url, client_secret?, session_id, processor }
  return res.json();
}

// NOTE: PayPal leg is "Staged — connect PayPal credentials in the NoblePort Payment Gateway".
// The gateway executes it once PayPal credentials are connected there.
18 ready-made flows

Example templates

One worked example for every flow type × processor × mode combination. Download the JSON definition or the client snippet, or load a template into the builder above to tweak it. PayPal blocks stay staged configuration until credentials are connected in the gateway. Downloaded bundles are stamped with a SHA-256 integrity block (plus a per-template checksum) that is verified on import — a modified bundle is rejected.

One-time payment · Stripe · Direct
Single 250 USD charge, executed by this app.
One-time payment · Stripe · Gateway
Single 250 USD charge, handed to the central NoblePort gateway.
One-time payment · PayPal · DirectNot runnable
PayPal cannot execute in Direct mode — switch the target to Gateway.
One-time payment · PayPal · Gateway
Single 250 USD charge, handed to the central NoblePort gateway. PayPal is exported as staged configuration only.
One-time payment · Both · Direct
Single 250 USD charge, executed by this app. PayPal is exported as staged configuration only.
One-time payment · Both · Gateway
Single 250 USD charge, handed to the central NoblePort gateway. PayPal is exported as staged configuration only.
Subscription · Stripe · Direct
Recurring 499 USD per year, executed by this app.
Subscription · Stripe · Gateway
Recurring 499 USD per year, handed to the central NoblePort gateway.
Subscription · PayPal · DirectNot runnable
PayPal cannot execute in Direct mode — switch the target to Gateway.
Subscription · PayPal · Gateway
Recurring 499 USD per year, handed to the central NoblePort gateway. PayPal is exported as staged configuration only.
Subscription · Both · Direct
Recurring 499 USD per year, executed by this app. PayPal is exported as staged configuration only.
Subscription · Both · Gateway
Recurring 499 USD per year, handed to the central NoblePort gateway. PayPal is exported as staged configuration only.
Deposit (partial payment) · Stripe · Direct
25% deposit of 4800 USD now, balance later, executed by this app.
Deposit (partial payment) · Stripe · Gateway
25% deposit of 4800 USD now, balance later, handed to the central NoblePort gateway.
Deposit (partial payment) · PayPal · DirectNot runnable
PayPal cannot execute in Direct mode — switch the target to Gateway.
Deposit (partial payment) · PayPal · Gateway
25% deposit of 4800 USD now, balance later, handed to the central NoblePort gateway. PayPal is exported as staged configuration only.
Deposit (partial payment) · Both · Direct
25% deposit of 4800 USD now, balance later, executed by this app. PayPal is exported as staged configuration only.
Deposit (partial payment) · Both · Gateway
25% deposit of 4800 USD now, balance later, handed to the central NoblePort gateway. PayPal is exported as staged configuration only.
18 flows · schema 1.3.0

Version report

A downloadable manifest of every exported flow in the bundle with its schema_version, template_id, template_version and builder version, plus a per-flow checksum. Take the JSON for tooling and the Markdown for humans.

VERSIONS CONSISTENTbuilder 1.3.0 · templates 1.1.0 · bundle 1.1
template_idschematemplatebuilderflowchecksum
one_time_stripe_direct1.3.01.1.01.3.0one_time/stripe/directsha256:e…7ce64443
one_time_stripe_gateway1.3.01.1.01.3.0one_time/stripe/gatewaysha256:b…879f17c1
one_time_paypal_direct1.3.01.1.01.3.0one_time/paypal/direct (not runnable)sha256:d…a177b14a
one_time_paypal_gateway1.3.01.1.01.3.0one_time/paypal/gatewaysha256:0…6a62cafd
one_time_both_direct1.3.01.1.01.3.0one_time/both/directsha256:d…dd07a7e1
one_time_both_gateway1.3.01.1.01.3.0one_time/both/gatewaysha256:1…462377b0
subscription_stripe_direct1.3.01.1.01.3.0subscription/stripe/directsha256:c…e79b327a
subscription_stripe_gateway1.3.01.1.01.3.0subscription/stripe/gatewaysha256:0…d7a9908e
subscription_paypal_direct1.3.01.1.01.3.0subscription/paypal/direct (not runnable)sha256:8…11f87834
subscription_paypal_gateway1.3.01.1.01.3.0subscription/paypal/gatewaysha256:7…66bfee76
subscription_both_direct1.3.01.1.01.3.0subscription/both/directsha256:d…43088783
subscription_both_gateway1.3.01.1.01.3.0subscription/both/gatewaysha256:a…f398b595
deposit_stripe_direct1.3.01.1.01.3.0deposit/stripe/directsha256:5…2482dc6c
deposit_stripe_gateway1.3.01.1.01.3.0deposit/stripe/gatewaysha256:5…918fb614
deposit_paypal_direct1.3.01.1.01.3.0deposit/paypal/direct (not runnable)sha256:d…3bc131f7
deposit_paypal_gateway1.3.01.1.01.3.0deposit/paypal/gatewaysha256:e…7a01feea
deposit_both_direct1.3.01.1.01.3.0deposit/both/directsha256:a…2fd2b5ab
deposit_both_gateway1.3.01.1.01.3.0deposit/both/gatewaysha256:e…66f52953
schema 1.3.0 → 1.3.0

Version diff

Pick a template (or an imported flow) and see exactly how it differs from the definition this builder exports right now — field-by-field, plus every schema changelog entry released in between.

5 added4 removed30 changedsame schema 1.3.0
changedamount.minor_units
25000
+ 49900
changedamount.value
250
+ 499
changedcharge_now.minor_units
25000
+ 49900
changedcharge_now.value
250
+ 499
changedid
flow_sea_esta_charter_day_pass
+ flow_sea_esta_host_membership
removedmetadata.fulfilment
instant
changedmetadata.product
charter_day_pass
+ host_membership
changedname
Charter Day Pass
+ Host Membership
changedpricing[0].amount.display
250.00 USD
+ 499.00 USD
changedpricing[0].amount.minor_units
25000
+ 49900
changedpricing[0].amount.value
250
+ 499
changedpricing[0].charge_now.display
250.00 USD
+ 499.00 USD
changedpricing[0].charge_now.minor_units
25000
+ 49900
changedpricing[0].charge_now.value
250
+ 499
changedpricing[1].amount.display
229.00 EUR
+ 459.00 EUR
changedpricing[1].amount.minor_units
22900
+ 45900
changedpricing[1].amount.value
229
+ 459
changedpricing[1].charge_now.display
229.00 EUR
+ 459.00 EUR
changedpricing[1].charge_now.minor_units
22900
+ 45900
changedpricing[1].charge_now.value
229
+ 459
changedprocessor
stripe
+ both
addedprocessors.paypal
+ {"intent":"SUBSCRIPTION","execution":"staged","execution_note":"Staged — connect PayPal c…
changedprocessors.stripe.line_items[0].price_data.currency_options.eur.unit_amount
22900
+ 45900
changedprocessors.stripe.line_items[0].price_data.product_data.name
Charter Day Pass
+ Host Membership
addedprocessors.stripe.line_items[0].price_data.recurring
+ {"interval":"year"}
changedprocessors.stripe.line_items[0].price_data.unit_amount
25000
+ 49900
changedprocessors.stripe.metadata.flow_type
one_time
+ subscription
removedprocessors.stripe.metadata.fulfilment
instant
changedprocessors.stripe.metadata.product
charter_day_pass
+ host_membership
changedprocessors.stripe.mode
payment
+ subscription
addedschedule
+ {"interval":"year","interval_count":1}
removedschema.template_id
one_time_stripe_direct
removedschema.template_version
1.1.0
changedtarget
direct
+ gateway
changedtype
one_time
+ subscription
changedwebhooks.events[3]
payment.captured
+ subscription.activated
changedwebhooks.events[4]
payment.refunded
+ subscription.renewed
addedwebhooks.events[5]
+ subscription.canceled
addedwebhooks.events[6]
+ payment.refunded
Schema validation

Import flow JSON

Paste or upload a nobleport.payment_flow definition or a nobleport.payment_flow_templates bundle. Every field is checked against the schema first — problems are listed with the exact JSON path so nothing loads into the builder half-broken.

/api/public/gateway/events

Webhook configuration

Staged — the gateway endpoint only records events and updates flow UI status. It never touches Stripe billing state, which stays owned by the existing Stripe webhook.

POST https://seaesta.lovable.app/api/public/gateway/events
checkout.completedcheckout.failedcheckout.canceledsubscription.activatedsubscription.renewedsubscription.canceledpayment.refunded
  1. Register the endpoint in the NoblePort Gateway
    In the gateway dashboard for “Sea-Esta”, add a webhook destination pointing at https://seaesta.lovable.app/api/public/gateway/events (POST, JSON).
  2. Subscribe to this flow's events
    checkout.completed, checkout.failed, checkout.canceled, subscription.activated, subscription.renewed, subscription.canceled, payment.refunded
  3. Generate a signing secret and store it as NOBLEPORT_GATEWAY_WEBHOOK_SECRET
    The gateway signs HMAC-SHA256 over "{timestamp}.{raw_body}" and sends it in x-nobleport-signature, with the unix timestamp in x-nobleport-timestamp. Add the same secret to this project's backend secrets.
  4. Scope the handler to UI status only
    The bundled handler verifies the signature, de-duplicates by event_id and records status for the UI. Stripe billing state stays owned by the existing Stripe webhook at /api/public/payments/webhook — do not write membership entitlements from gateway events.
  5. Send a test event and confirm a 200
    Use the gateway's “Send test event” action with checkout.completed. A 401 means the secret differs; a 400 means the timestamp is outside the 5-minute tolerance.
// Sea-Esta → NoblePort Gateway webhook receiver (PLACEHOLDER)
// Route: POST /api/public/gateway/events   Flow: flow_sea_esta_host_membership
//
// Staged — the gateway endpoint only records events and updates flow UI status. It never touches Stripe billing state, which stays owned by the existing Stripe webhook.
import { createFileRoute } from "@tanstack/react-router";
import { createHmac, timingSafeEqual } from "node:crypto";

const TOLERANCE_SECONDS = 300;
const HANDLED_EVENTS = [
  "checkout.completed",
  "checkout.failed",
  "checkout.canceled",
  "subscription.activated",
  "subscription.renewed",
  "subscription.canceled",
  "payment.refunded"
] as const;

function verify(raw: string, timestamp: string, signature: string, secret: string) {
  const age = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (!Number.isFinite(age) || age > TOLERANCE_SECONDS) return false;
  const expected = createHmac("sha256", secret).update(`${timestamp}.${raw}`).digest("hex");
  const a = Buffer.from(signature);
  const b = Buffer.from(expected);
  return a.length === b.length && timingSafeEqual(a, b);
}

export const Route = createFileRoute("/api/public/gateway/events")({
  server: {
    handlers: {
      POST: async ({ request }) => {
        const secret = process.env["NOBLEPORT_GATEWAY_WEBHOOK_SECRET"];
        if (!secret) return Response.json({ received: true, staged: true });

        const raw = await request.text();
        const signature = request.headers.get("x-nobleport-signature") ?? "";
        const timestamp = request.headers.get("x-nobleport-timestamp") ?? "";
        if (!verify(raw, timestamp, signature, secret)) {
          return new Response("Invalid signature", { status: 401 });
        }

        const event = JSON.parse(raw) as { id: string; type: string; data?: unknown };
        if (!HANDLED_EVENTS.includes(event.type as never)) {
          return Response.json({ received: true, ignored: event.type });
        }

        // TODO: persist UI status for event.id (idempotent upsert on event_id).
        // Do NOT grant entitlements here — Stripe billing state is owned by
        // the existing Stripe webhook.
        console.log("[nobleport] gateway event", event.id, event.type);

        return Response.json({ received: true });
      },
    },
  },
});

How the Launchpad and the Gateway relate

This app remains the live Stripe implementation for Sea-Esta memberships. The Launchpad is the flow-builder companion to the central NoblePort Payment Gateway: you design a flow once, run it locally on Stripe, or ship it to the gateway where Stripe and PayPal credentials live and where every NoblePort dapp calls the same REST API with its own app key.