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 already hit.
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. No involvement from you, at any hour.
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 doesn't proxy anything and takes no cut of your sales — we only create the invoice and catch the payment notification.
How it works#
- A person moves through the funnel and reaches the Payment step.
- 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.
- The person pays on the Lava page.
- 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 — a fork worth taking deliberately.
| 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 rise) | 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 — we'll pull it and tell 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. Set up the webhook#
The webhook is how Lava tells us "payment received". Without it the bot never learns about the payment and never delivers access.
In Lava: Integrations → API → Webhooks → Add.
| Field | What to enter |
|---|---|
| URL | https://craftopen.space/api/payments/webhook |
| Event type | Payment result |
| Authentication | API key of your service |
| API key | The secret we give you — see the warning below |
🔴 The "API key" field is NOT your Lava key. The field name is misleading. It's a password Lava uses to identify itself to us so we know the notification is genuine. We generate that secret and send it to you — paste it here. Your Lava key does not belong in this field.
Step 4. Send us the keys#
For now we connect accounts manually — message us on Telegram with:
- Your Lava API key (Integrations → API → create key) — the bot uses it to issue invoices on your behalf.
- The product link — we'll send back the offerId and your webhook secret.
We'll wire it up and tell you when you can test. It usually takes a few minutes.
⚠️ Your Lava key can issue charges in your name. Send it to us only, in a direct message — never post it in group chats or screenshots. If a key leaks, delete it in the Lava dashboard and create a new one.
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.
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". 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.
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.
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 cards 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:
- 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).
- In the Payment step, tick "This funnel sets the price".
- The amount comes from that step's "Price" field. Want 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:
- Walk 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.
- 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.
- 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.
- Temporarily set a small price (on the Lava product, or in the "Price" field of the Payment step if the funnel owns the price).
- Pay it yourself, once per method if you sell with both card and SBP.
- Confirm access arrives in the bot automatically.
- 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.
Walking 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:
- Save your live settings first — write down every step's delay before you change anything, or you won't restore the timing exactly.
- 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.
- Walk the funnel from another account that has never been through it: someone who already went through lands mid-funnel, not at the start.
- Walk it twice: once tapping nothing — you'll see the whole follow-up chain; once tapping through — you'll see the short path.
- Pay both branches with the small amounts and confirm access arrives on its own.
- 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.
- Is the webhook set up in Lava, and is the right secret in the "API key" field? No webhook means Lava never told us about the payment, so the bot could not possibly have reacted.
- 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.
- Did they buy through the funnel button rather than a direct product link (see the warning above)?
- 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 |
| "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:
- Refunds. If you refund a buyer, their access stays — revoke it manually.
- 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 against real requests.