Skip to main content

Pay Link Integration Guide

This guide covers where to create pay links in your application flow and how to show them to customers.


Step 1 — Create the order in your system first

Before calling the Coinsnap API, your own system should create the order or invoice internally. The pay link belongs to a specific business transaction — your order is the source of truth.

At minimum you need:

  • Your own internal order ID or invoice number
  • The order amount and currency
  • Optionally: customer name or email, description, success URL

Example order:

  • Order ID: ORD-2026-1045
  • Customer: John Smith
  • Amount: €149.00

This order ID becomes the key reference between your system and Coinsnap. It will appear in every webhook event so you can match payments back to orders.


After the order exists in your system, call the Coinsnap API to create a pay link.

Node.js
async function createOrder(cart, customer) {
// 1. Save the order to your database
const order = await db.orders.create({
customerId: customer.id,
total: cart.total,
currency: cart.currency,
status: 'pending_payment',
});

// 2. Create a pay link for this order
const res = await fetch(
`https://app.coinsnap.io/api/v1/stores/${process.env.COINSNAP_STORE_ID}/payment-requests`,
{
method: 'POST',
headers: {
'x-api-key': process.env.COINSNAP_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: cart.total,
currency: cart.currency,
orderId: order.id,
title: customer.name,
customerEmail: customer.email,
description: `Order ${order.id}`,
redirectUrl: `${process.env.APP_URL}/orders/${order.id}/success`,
}),
}
);

const payLink = await res.json();

// 3. Store both the ID and URL against your order
await db.orders.update(
{ id: order.id },
{ payLinkId: payLink.id, payLinkUrl: payLink.url }
);

return { order, payLinkUrl: payLink.url };
}

You have four options. Pick the one that fits your workflow.

Option A — On the order confirmation page

Show the pay link immediately after the customer places an order. Bitcoin is offered as an alternative to whatever payment method they chose.

<div class="payment-option">
<h3>Pay with Bitcoin</h3>
<p>Scan or click to pay with Bitcoin or Lightning.</p>
<a href="{{ order.payLinkUrl }}" class="btn">Pay with Bitcoin →</a>
</div>

Option B — In the order confirmation email

Include the pay link in the transactional email sent after order creation. The customer pays when convenient.

Node.js — order confirmation email
await sendEmail({
to: customer.email,
subject: `Order ${order.id} confirmed`,
html: `
<p>Hi ${customer.name},</p>
<p>Your order has been confirmed.</p>
<p>Pay with Bitcoin: <a href="${order.payLinkUrl}">${order.payLinkUrl}</a></p>
<p>This link is valid for 30 days.</p>
`,
});

Option C — In the customer account area

Store the pay link and display a "Pay with Bitcoin" button on unpaid orders in the customer's account.

{% if order.status == 'pending_payment' %}
<a href="{{ order.payLinkUrl }}">Pay with Bitcoin</a>
{% endif %}

Option D — On an invoice PDF or email

For B2B and invoice-based billing, include the pay link the same way you'd include bank transfer instructions.

Instead of:

Please transfer EUR 149.00 to IBAN DE12... with reference ORD-2026-1045

Include:

Pay this invoice with Bitcoin: [pay link URL]

All payment details — amount, currency, your order reference — are already embedded in the link. The customer clicks and pays. No manual entry of IBAN or reference number.


Step 4 — Handle payment confirmation

Register a webhook endpoint in Coinsnap Dashboard → Webhooks and handle the Settled event to mark the order as paid.

Webhook handler (Node.js)
case 'Settled': {
const orderId = event.metadata?.orderId;

const order = await db.orders.findById(orderId);
if (order.status === 'paid') break; // idempotency guard

await db.orders.update({ id: orderId }, {
status: 'paid',
paidAt: new Date(),
});

await triggerFulfillment(orderId);
break;
}

See Handle Payment Result for the full webhook guide including all event types.


End-to-end flow

  1. Customer places an order in your application
  2. Your system creates the order (status: pending_payment)
  3. Your application calls the Coinsnap API to create a pay link
  4. Coinsnap returns the pay link ID and URL
  5. Your system stores both against the order
  6. The customer receives the pay link (confirmation page, email, or account area)
  7. The customer opens the pay link
  8. Coinsnap shows the hosted payment page with order details prefilled
  9. The customer clicks "Pay with Bitcoin"
  10. Coinsnap generates a Bitcoin invoice at the current exchange rate
  11. The customer pays via Lightning or Bitcoin
  12. Coinsnap sends a Settled webhook to your server
  13. Your server marks the order as paid and triggers fulfillment

Create one pay link per order and reuse it. Do not create a new pay link every time the customer views their order — the same URL remains valid as long as the order is unpaid and the expiry date hasn't passed.