lasso

Test merchant

OverviewData mapAdditional SignalsConciergeAttemptsRecommendationsIntegration

Login to access your storefront's Lasso.

Guided demoBack to home
OverviewData mapAdditional SignalsConciergeAttemptsRecommendationsIntegration

Integration

Connect your store, send Lasso your declines, and hook up your AI agent. Start with Visa Acceptance, or with the Stripe webhook if you already use Stripe.

Where does your store run?

Pick one to see where to start. All paths share the same dashboard.

Visa Acceptance. Start here. Lasso takes payments through Visa Acceptance's hosted card fields and diagnoses every decline as it happens, using Visa's own response categories.

Set up Visa Acceptance ↓

Built for Visa

Lasso treats Visa as a first-class network: it takes payments through Visa Acceptance, reads declines the way Visa defines them, and follows Visa's rules on when to try again.

  • Visa Acceptance, built in

    Signs in with a shared-secret JWT and takes cards through Visa's hosted fields (Microform). Lasso only ever receives a one-time token, never a card number or security code.

  • Visa's decline categories

    Every Visa decline is sorted into Visa's four response categories, so a retry follows the network's rules: category 1 is never retried, and the rest stay within reattempt limits.

  • Recovery you can trust

    An order is marked paid only when capture is confirmed. An authorization alone stays pending, and recovered revenue is counted once.

  • Advice that cites Visa

    Recommendations on network tokens, 3-D Secure data and Account Updater quote the figures Visa publishes, with the evidence from your own declines beside them.

Set up in four steps

  1. 1

    Connect your processor

    Give Lasso your credentials so it can take payments and read results. Choose Visa Acceptance, or connect Stripe with a webhook.

    1. In the Visa Acceptance sandbox, create a REST shared-secret key (the JWT option).
    2. Put the merchant ID, key ID and shared secret in Lasso's server environment. They never go to the browser.
    3. Set your HTTPS checkout origin. Visa's hosted fields only mount on the exact origin you configure.
    4. Run the readiness check. It prints yes or no for each requirement and never shows a key.
    .env
    # Lasso server environment (Visa Acceptance)
    DEMO_MODE="false"
    PAYMENT_PROCESSOR="visa_acceptance"
    VISA_ACCEPTANCE_MERCHANT_ID="your_merchant_id"
    VISA_ACCEPTANCE_KEY_ID="your_key_id"
    VISA_ACCEPTANCE_SHARED_SECRET="your_shared_secret"
    VISA_ACCEPTANCE_TARGET_ORIGIN="https://your-checkout.example.com"
    APP_BASE_URL="https://your-lasso-url.example.com"
    Prepare and check
    # Prepare a dedicated database, then check readiness.
    # Preflight prints yes/no readiness only, never your keys.
    pnpm sandbox:setup
    pnpm visa:preflight
  2. 2

    Send Lasso your declines

    Pick the depth that fits your stack. With Visa Acceptance, Lasso sits inside the payment flow, so every decline is diagnosed as it happens. With Stripe, a webhook alone fills your dashboard. Add the REST routes, the script or an SDK for rescue prompts and the concierge on your checkout.

    text
    # 1. Your server asks Lasso for a payment session (the amount is set server-side)
    POST /api/payments/visa/session
      -> { orderId, sessionId, amount, currency,
           captureContext, clientLibrary, clientLibraryIntegrity }
    
    # 2. Your checkout mounts Visa's Microform hosted fields with that captureContext.
    #    The shopper types card details into Visa's fields, never into your page.
    #    You get back a one-time transient token.
    
    # 3. Send Lasso the token (never card data)
    POST /api/payments/visa/submit
      { orderId, sessionId, operationId, transientToken, billing: { ... } }
    
    # 4. Check the result. Lasso diagnoses any decline and offers a safe next step
    GET /api/payments/visa/operations/{operationId}?orderId={orderId}
      -> { state: "paid" | "declined" | "pending" | "blocked",
           result?, orderOpenUntil? }
  3. 3

    Verify the connection

    Check that Lasso is ready, then make a payment and watch it appear in the dashboard.

    Check readiness
    curl "$LASSO_URL/api/integrations/status"
    
    {
      "mode": "visa_acceptance",
      "visaAcceptance": { "configured": true },
      "databaseFingerprint": "…",
      "stripe": {
        "testKeyConfigured": false,
        "publishableTestKeyConfigured": false,
        "webhookReady": false
      }
    }

    Run pnpm visa:test-orders to create sample orders, one checkout link each. Each has a fixed amount that returns a known result:

    • approveAuthorized, then capturedConfirmation
    • invalid-accountDeclined, invalid accountFix the card number
    • expired-cardDeclined, expired cardFix the expiry
    • invalid-cvcDeclined, invalid security codeFix the security code
    • stolen-lostDeclined, lost or stolenGeneric message only; a retry is blocked

    Use Visa's public test card in the hosted fields to see diagnosis and retry blocking. Then open Attempts and filter by Visa Acceptance to see them.

  4. 4

    Go live

    Choose what Lasso is allowed to do for your shoppers. You can change any of it later.

    • Rescue prompts

      Show one safe next step after a decline: fix the field, try another card, or pay another way.

    • Pay-later links

      Opt-in only: the shopper ticks a consent box first. Available with Stripe today; on Visa checkout it is coming next.

    • Concierge

      Set discount caps, margin floors and pickup or shipping offers. Nothing changes until the shopper says yes.

    • Languages

      Rescue copy is available in English, Spanish, Chinese, Vietnamese, Tagalog and Korean.

    Concierge limits live in the Concierge settings.

Connect your AI agent with MCP

Preview

MCP (Model Context Protocol) is an open standard that lets AI assistants call tools on a server. Add Lasso as an MCP server and your assistant can answer questions from your own decline data and draft the fixes, all from chat. The server is read-only by default, and nothing is applied without your approval.

Preview: this shows the planned interface. It is not published yet.

bash
claude mcp add lasso \
  --env LASSO_API_URL=https://your-lasso-url.example.com \
  --env LASSO_API_KEY=lasso_... \
  -- npx -y @lasso/mcp-server

Tools the server exposes

  • decline_summary

    Lost, recovered and recoverable revenue for a date range, with the top decline driver.

  • explain_attempt

    Who said no on one attempt, which Visa category it falls in, and what Lasso offered.

  • search_attempts

    Find attempts by reason, card network, processor (Visa Acceptance or Stripe), amount or date.

  • list_recommendations

    The current recommendations, with the evidence behind each.

  • draft_recommendationDraft only

    Draft the processor request or the rule change for a recommendation, for you to review.

What it looks like in your assistant
You:    Why did we lose $19k this month, and what should I fix first?

Claude: [calls decline_summary(range="30d")]
        Declines cost $19,640 in the last 30 days. Most come from customers'
        banks (62%), mainly Visa category 2 (issuer cannot approve now).
        Your own filter blocked 11 returning customers, which is the
        cheapest thing to fix.

You:    Draft the change for that.

Claude: [calls draft_recommendation(id="REVIEW_FILTER_RULE")]
        Here is a draft that skips the block when the card has a prior
        successful payment and the risk level is below "highest". Nothing
        has been applied; approve it in the Lasso dashboard.

Let your coding agent build it

Paste this into Claude Code, Cursor or any coding assistant that can edit your repo. It names the real routes for Visa Acceptance and Stripe and the rules to follow, so the result matches how your store is built.

Prompt for your coding agent
You are adding Lasso (payment-decline recovery) to this storefront.

Goal: when a payment fails, show the shopper one safe next step, and send the
result to Lasso so the merchant dashboard can explain the decline.

Pick the path that matches how this store takes payments.

A. Visa Acceptance (preferred):
   1. Find the checkout page and the server code that creates the order. Do not
      change pricing or catalog logic; the amount must stay server-owned.
   2. Call POST /api/payments/visa/session for the order, then mount Visa's
      Microform hosted fields using the returned captureContext,
      clientLibrary and clientLibraryIntegrity.
   3. On submit, send {orderId, sessionId, operationId, transientToken, billing}
      to POST /api/payments/visa/submit. Never send or store card numbers.
   4. Poll GET /api/payments/visa/operations/{operationId}?orderId=... and show
      the shopper ONLY the returned message and next step. Treat "pending" as
      pending, never as paid.

B. Stripe:
   1. In Stripe, add a webhook endpoint pointing at
      https://YOUR-LASSO-URL/api/webhooks/stripe for these events:
      payment_intent.succeeded, payment_intent.payment_failed,
      charge.succeeded, charge.failed.
   2. After a failed payment, call POST /api/payments/attempt-result with
      {"paymentId", "orderId"} and show only the message it returns.

For both: when the shopper acts on a rescue prompt, call POST /api/rescue/event
with {"attemptId", "remedyId", "action": "shown" | "accepted" | "dismissed"}.

Rules:
- Never show shoppers a decline code, a card network name, or a reason the bank
  suspects fraud. Use the returned message verbatim.
- Keep all keys server-side. Never log full card numbers or CVCs.
- Follow-up emails must be opt-in: only create one when the shopper ticked the
  consent box.

What Lasso will and won't do

  • Card numbers and security codes never reach Lasso. Visa's hosted fields send a one-time token, and keys stay on the server.
  • An authorization alone never marks an order paid. Lasso waits for confirmed capture.
  • Shoppers never see decline codes, network names or fraud signals. They get one plain next step.
  • Retries are enforced by a server-side ledger that follows each network's reattempt rules, so blocked retries cost nothing.
  • Follow-up messages are opt-in, and demo delivery is labelled as simulated.