Docs · Funnels and payments

Taking payments in a funnel with Lava

Sell right inside the chat — the buyer taps a button, pays, and the bot delivers access on its own. Step by step, including the pitfalls we've already run into.

Updated: September 26, 2026

Your funnel can take money: a person reaches the Payment step, gets a button, pays — and the bot delivers access and continues the funnel by itself. You don't have to do anything, day or night.

Payments run through Lava.top — a payment service that works with individuals and sole proprietors and accepts cards and SBP (Russia's instant bank transfer system).

💡 The money goes to you directly. You have your own Lava account and your own agreement with them. Craft never holds your money and takes no cut of your sales: we only create the invoice and receive the payment notification.

How it works#

  1. A person moves through the funnel and reaches the Payment step.
  2. The bot creates a personal invoice in your Lava account and sends a pay button — on Telegram, two at once: ⚡️ Pay via SBP and 💳 Pay by card.
  3. The person pays on the Lava page.
  4. Lava notifies us, the bot recognises the buyer and continues the funnel — along the arrow leading out of the Payment step. That's where you hand over access: a channel link, a chat invite, a file.

All you do is set it up once. After that the funnel runs on its own.


What you'll need#

  • A lava.top account with a confirmed payout method.
  • A funnel already built in Craft (Telegram or Instagram).
  • 15 minutes.

⚠️ Telegram is the reliable option. On Instagram, access can only be delivered if the person messaged you within the last 24 hours — that's Meta's rule and there is no way around it. Since paying can easily take longer than a day, move people from Instagram to Telegram and sell there.


Step 1. Create a product in Lava#

In your Lava dashboard: Create → Digital product.

Fill in:

  • Description — what the person is buying.
  • "After payment" (the paid part) — put your channel/chat links here. Lava also emails them to the buyer. That's your safety net: even if something happens to the bot, the buyer still gets access.
  • Price — you can set it in several currencies at once.

Then publish the product.

🔴 A draft doesn't count. An unpublished product isn't visible over the API — we simply can't issue an invoice for it, and it will look like "the key is wrong". Make sure the product is published.

Both fields — description and the paid part — are required: the product won't save without them.

Who owns the price: Lava or the funnel#

The product has a "Price on request via API" toggle. It decides where the invoice amount comes from, so choose on purpose.

Toggle off (default) Toggle on
Price is set by Lava — whatever you typed into the product the funnel — the "Price" field of the Payment step
To change the price edit it in Lava edit it in the funnel
Several prices (sale, price increase) needs a second product one funnel, one product
Product on the Lava storefront sells directly sells only through the funnel

One price that never changes → leave it off, it's simpler. Planning a "price goes up in 24 hours" timer, sales, or different prices per branch → turn it on: see The funnel sets the price.

🔴 If you're going to turn it on, grab the offerId first (step 2), then flip the toggle. Once it's on, the product disappears from the list Lava returns, and there is nowhere left to read the offerId from.


Step 2. Get the offerId#

An invoice needs the offerId — which is NOT the number you see in the product's address.

🔴 The most common mistake. The address bar (app.lava.top/products/XXXX) shows the product id. It will not work. The offerId lives inside the product and isn't shown in the dashboard. Paste the wrong one and payment fails with "product not found".

Two ways to get it:

The easy way: send us the product link and we'll look it up for you.

On your own (if you're comfortable with the command line) — use your Lava key:

curl -s "https://gate.lava.top/api/v2/products?showAllSubscriptionPeriods=true" \
  -H "X-Api-Key: YOUR_LAVA_KEY"

Find your product in the response — the value you need is under offers → id. It looks like 8665127d-....

💡 How to confirm the offerId is yours. Someone else's offerId with your key won't work — Lava replies that you can only sell your own products. That's a handy way to verify the money will land in the right account.

🔴 Grab the offerId BEFORE you turn on "Price on request via API". With that toggle on, the product vanishes from the list — the request returns zero products, and it looks like a wrong key or an unpublished product. Save the offerId somewhere first.


Step 3. Connect Lava in Craft#

In Craft: Settings → "Payments in funnels (Lava)". Paste your Lava API key (in Lava: Integrations → Public API) and click "Connect". Craft checks the key with Lava right away — a wrong key shows up here, not at your first sale.

🔴 Never forward the key to anyone. It allows issuing invoices on your behalf. Paste it only on this page; it must not end up in chats, in an AI conversation or on screenshots. If it leaks — delete it in Lava, create a new one and paste it again.

Once connected, the same page shows the webhook URL and the secret you need for the next step, plus a "Products and their ids" button that lists your products and the exact offerId used by the Payment step.


Step 4. Set up the webhook#

The webhook is how Lava tells us what happened to a payment: succeeded, failed, refunded. Without it the bot never learns about the payment and grants no access.

In Lava: Integrations → Public API → Add Webhook.

Field What to enter
URL the address shown on the Craft settings page (https://craftopen.space/api/payments/webhook)
Events Tick all four: payment succeeded, payment failed, refund succeeded, chargeback initiated
Authentication API key of your service
API key the secret from the Craft settings page — there's a Copy button next to it

🔴 Tick "payment failed" too. Without it the bot never learns that someone's card was declined — they stay on the Lava error page and you never find out you lost a buyer. If you set the webhook up before September 2026, open it and check all four events.

🔴 The "API key" field is NOT your Lava key. The label is confusing. It is a password Lava uses to identify itself to us so we know the notification is genuine. Craft gives it to you on the settings page. Your Lava key does not belong here and it isn't safe to put it there.

If you click "New secret" in Craft, put the new secret into the Lava webhook right away — otherwise Lava's notifications stop passing the check and access after payment is no longer granted.


Step 5. Build the Payment step#

In the funnel builder, add a Payment step and fill in:

  • Lava product (offerId) — the one from step 2.
  • Price (for display) and Currency — these only affect the message text; Lava charges the product's own price.
  • Message with the pay button — your offer copy; buttons appear underneath it.
  • Button text — used when there's only one payment method.
  • E-mail variable — where the buyer's e-mail is stored.

🔴 Collect the e-mail BEFORE the payment step. Lava won't issue an invoice without the buyer's e-mail. Put a Question step before Payment — "Which e-mail should we send access to?" — and save the answer into a variable (email by default). Without it the payment step simply won't fire.

How to ask for it so people don't drop off. "We'll send you a receipt" reads as optional — the buyer thinks "I don't need a receipt" and simply doesn't reply. That's an expensive loss: they had already agreed to pay. Don't say "we can't proceed without it" — say what happens once they send it:

One step left. Send me your email: I'll use it for your order and reply with the payment button right away. The receipt goes there too. And I'll send access to the course here in this chat, right after payment.

And give that Question step a timeout with a reminder — otherwise anyone who gets distracted disappears silently.

The arrow leaving the Payment step is where the funnel continues after a successful payment. That's the step where you deliver access: the private channel link, the chat invite, the file.

Payment methods#

On Telegram the buyer gets two buttons: "⚡️ Pay via SBP" and "💳 Pay by card (Russian cards)". That converts better — people pay with what they're used to.

  • Currency other than the rouble → card only (SBP is rouble-based).
  • If one of the methods isn't enabled on your Lava account, the other buttons still arrive — the funnel doesn't break.

Foreign cards get their own button. "💳 Pay by card (Russian cards)" issues a rouble invoice, and it does not take foreign cards: the payment page hangs and the charge never reaches the bank (confirmed with a real payment). If some of your buyers are abroad, fill in "Price for foreign cards" on the Payment step — for example, $49. A third button appears, "🌍 Pay with a foreign card": a dollar or euro invoice that accepts cards from any country.

  • It works with "The funnel sets the price" ticked. If the Lava product holds the price, the product needs a price in that currency.
  • Pick a round number close to the rouble price — for example, 3,490 ₽ → $49.
  • Telegram only for now.
  • Apple Pay. Under the price field there's a tick box, "Button '🍎 Apple Pay with a foreign card'" — one more button at the same foreign price. The foreign card page doesn't offer Apple Pay on its own, so it gets its own button. It works on iPhone and Mac with a foreign card in Wallet: Russian cards can't be added to Apple Pay, and Lava doesn't take it in roubles.
  • PayPal. One more tick box — "Button '🅿️ Pay with PayPal'": an invoice at the same foreign price for people without a suitable card. PayPal must be enabled in your Lava account — if it isn't, Lava refuses and the buyer simply won't see this button (the others stay).
  • Payment page in English. The foreign buttons (card, Apple Pay, PayPal) open the Lava page and payment emails in English — since buyers abroad are the ones who use them. Rouble buttons stay in Russian.
  • Confirmation takes longer. A rouble payment reaches the bot within a couple of seconds; a foreign one sometimes takes 5–10 minutes: the payment page sends the buyer straight back to the bot, and access arrives once the bank settles the charge. So the buyer doesn't panic or pay twice, say so in the Payment step text — for example: "Occasionally the bank takes 5–10 minutes to confirm a payment — your access will still arrive here on its own, no need to pay again."

On Instagram a single pay button arrives — card. One more reason to move buyers to Telegram if you sell in Russia.

🔴 Don't hand out the direct Lava product link. A purchase made outside the funnel isn't tied to a specific person — the bot won't know who to deliver to and automatic delivery won't happen. Use the button from the Payment step only.

When someone doesn't pay#

The most expensive spot in a funnel is the person who opened the payment page and closed it. So they aren't left in silence, the Payment step has a “Follow-up if unpaid” field: how long to wait for the payment before sending them down a separate branch.

Fill it in and the step grows a second output, “Did not pay”. Wherever that arrow leads is where the funnel goes if the payment never arrives.

What to write in that message: usually the person didn't pay not because they changed their mind, but because their bank declined the charge or the link opened in the wrong browser. Offer the other payment method (card instead of SBP or the other way round) and your personal contact. And add a button that leads back to the Payment step — it issues a fresh invoice.

A sensible wait is 10–20 minutes: people either pay right away or have already moved on.

Leave the field empty and there is no branch — someone who doesn't pay hears nothing more.

When the bank declines the payment#

This is a different case: the person wanted to pay, but the card didn't go through — not enough funds, the bank blocked it, the code wasn't confirmed. Here the bot acts on its own, nothing to set up:

  1. It tells the person why it failed, in plain words, and suggests another method — card instead of SBP, or a different card.
  2. It immediately sends fresh payment buttons on the same step, at the same price.
  3. It tells you: who, how much, which method and what the bank said. If they don't pay soon, message them yourself — this person wanted to buy.

If someone tried SBP and then paid by card, they won't get a "didn't go through" message. Two failures in a row produce one message, not two.

After paying or failing, Lava sends the person back to the chat with the bot instead of leaving them on its own page.

⚠️ Failed-payment and refund notifications reach you on Telegram if a Telegram account is linked to your Craft account. If it isn't, we receive the notification and pass it on. Linking is more reliable — you hear about it straight away.

The same applies to the “Question” step you use to collect the e-mail: it has a timeout and a “No answer” output. Without it, someone who starts the purchase and drops off at the e-mail field also disappears silently. Set 5 minutes and a reminder: “Still waiting for your e-mail.”


The funnel sets the price (sales and timers)#

Normally the price lives in the Lava product. Then "the price goes up in 24 hours" or "a discount for this branch" needs a second product — and from there you're juggling two products and two offerIds.

There's a second mode: the funnel sets the invoice amount. One Lava product serves any price, and price rises and sales are built as funnel branches.

How to turn it on:

  1. In Lava, enable "Price on request via API" on the product (you should already have the offerId by now — see the warning in step 2).
  2. In the Payment step, tick "This funnel sets the price".
  3. The amount comes from that step's "Price" field. Need a second price? Add a second Payment step on another branch with a different price.

What you get: the price in the message and the price on the invoice are now the same number from the same field — nothing can drift apart. A "sale ends in" timer, different prices per keyword, a returning visitor seeing the new price — all of it is branches of one funnel.

✅ Verified with real payments. One funnel, one product: the first branch issued an invoice for 3490 ₽, the second for 4990 ₽, and the Lava page showed exactly our amount. USD and EUR work too.

What to know upfront:

🔴 The amount becomes your responsibility. While Lava owned the price there was nothing to get wrong. Now a typo in the "Price" field is a real charge. The dangerous combination is "amount still in roubles, currency switched": 3490 ₽ becomes $3490. We do guard this: if the currency isn't the rouble and the amount is above 1000, no invoice is created at all and you get a warning in your bot. Checking the currency/amount pair is still on you.

⚠️ The product disappears from the Lava storefront — it can no longer be bought directly, only through the funnel. If you were also selling from the storefront, this mode isn't for you.

⚠️ The minimum for roubles is 50 ₽. Lava rejects anything smaller ("the amount is too small"). Keep it in mind for test payments.

⚠️ Telegram funnels only for now. On Instagram the price stays in the Lava product.


How to test it#

Cheapest checks first.

Without spending money:

  1. Go through your own funnel to the Payment step and wait for the buttons. Buttons appeared — your key works, the product is published and the offerId is right.
  2. Tap the button and look at the page: is there a choice of method, the right amount, the right product name? Don't pay — creating an invoice by itself touches no money.
  3. Check that the funnel asks for an e-mail before payment and remembers it.

With money (the final check, once):

Lava has no test mode — that's their official answer. So the only way to verify the whole chain is one real payment for a small amount.

  1. Temporarily set a small price (on the Lava product, or in the "Price" field of the Payment step if the funnel owns the price).
  2. Pay it yourself, once per method if you sell with both card and SBP.
  3. Confirm access arrives in the bot automatically.
  4. Restore the real price immediately.

🔴 While a test price is live, anyone can buy at that price. The product is published and visible to everyone. Put the real price back right away, not "later".

💡 About the fee. Lava keeps a fee on every payment — check the exact figure in your dashboard and plan. In our test it kept roughly 8% of a small payment.

Testing the whole funnel#

If your funnel has follow-ups on timers and more than one price, testing it "as is" takes a day. The fast way:

  1. Save your live settings first — write down every step's delay before you change anything, or you won't restore the timing exactly.
  2. Set all delays to 5 seconds and the prices to small and different values (say 50 ₽ and 55 ₽), so the amount tells you which branch fired.
  3. Walk the funnel from another account that has never been through it: someone who already went through lands mid-funnel, not at the start.
  4. Walk it twice: once tapping nothing — you'll see the whole follow-up chain; once tapping through — you'll see the short path.
  5. Pay both branches with the small amounts and confirm access arrives on its own.
  6. Restore the live delays and prices.

💡 If a message arrives a minute or two late during your test run — most likely the service was being updated at that moment. Nothing is lost, the queue catches up. Don't rush to fix a funnel that works.


They paid, but got no access#

Check in this order — nine times out of ten it's one of the first two.

  1. Is the webhook set up in Lava, is the right secret in the "API key" field, and are all four events ticked (step 3)? No webhook means Lava never told us about the payment, so the bot could not possibly have reacted.
  2. Instagram and the 24-hour rule. If the payment happened more than a day after the person's last message, Meta won't let the bot write to them.
  3. Did they buy through the funnel button rather than a direct product link (see the warning above)?
  4. Did the e-mail reach the payment step? An empty e-mail variable means no invoice.

Still stuck — message us on Telegram with the payment time and the buyer's e-mail. We'll check what arrived on our side and, if needed, deliver access manually — the buyer gets it in the bot exactly as with a normal payment.


Common mistakes#

Symptom Cause
Pay buttons never arrive offerId is empty, or no e-mail collected before the payment step
The bot says "Lava doesn't accept this e-mail" It's the e-mail of your own Lava account — you can't buy your own product with it
Someone's card was declined and you never heard "Failed payment" isn't ticked in the webhook, or no Telegram is linked to your Craft account
"Product not found" Pasted the product id from the address bar instead of the offerId
We "can't see" a product you created It's an unpublished draft — or "Price on request via API" is on (then it shouldn't be visible)
Invoice for the wrong amount The funnel owns the price and the "Price" field has a typo
No invoice, plus a warning about the amount Non-rouble currency with a rouble-sized amount — we stopped the charge
"The amount is too small" Lava won't accept less than 50 ₽
Payment went through, no access The webhook isn't set up, or holds the wrong secret
Someone bought, the bot did nothing The purchase came from a direct product link, bypassing the funnel
Access never arrived on Instagram More than 24 hours passed since the person's last message

Not supported yet#

Being upfront about the limits, so there are no surprises:

  • Automatic access removal on refund. We tell you right away about a refund or a bank dispute, but removing the person from the channel or chat is up to you.
  • Subscriptions and recurring payments. One-off purchases only for now.
  • Funnel-owned prices and the choice of payment method are Telegram-only. On Instagram the price lives in the Lava product and there's a single button.
  • Connecting keys yourself. For now it goes through us and takes minutes.

Need something from this list — tell us. We build what people actually ask for.

Didn't find an answer?Message us on Telegram or email [email protected] — we'll reply and extend the article.
Message on Telegram