Create a Pay Link
Pay links are created with a single API call. The response returns the pay link ID and the shareable URL. Store both against your order record.
Endpoint
POST https://app.coinsnap.io/api/v1/stores/{storeId}/payment-requests
Authentication: x-api-key header with your API key.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Fiat amount to charge. Must be greater than 0. |
currency | string | No | 3-letter currency code (EUR, USD, etc.). If omitted, the backend accepts the request and applies its default handling. |
title | string | Yes | Customer-facing label — customer name, company, or order label |
orderId | string | No | Your internal order or invoice number — echoed back in every webhook event |
description | string | No | Short description shown to the customer on the payment page |
redirectUrl | string | No | Where to send the customer after successful payment |
customerEmail | string | No | Pre-filled customer email |
discount | number | No | Bitcoin discount as a percentage (e.g. 5 = 5% off) |
internalNote | string | No | Merchant-only note, not visible to the customer |
expiryDate | string | No | ISO 8601 datetime. Defaults to 30 days from creation. |
Response
{
"id": "3JUseUusmduemKeJkv3H",
"url": "https://pay-link.coinsnap.io/payment-requests/3JUseUusmduemKeJkv3H"
}
| Field | What to do with it |
|---|---|
id | Store in your database — use to check status or update the pay link via API |
url | Share with your customer — works in emails, PDFs, buttons, and QR codes |
Code examples
- cURL
- Node.js
- PHP
- Python
curl -X POST \
'https://app.coinsnap.io/api/v1/stores/YOUR_STORE_ID/payment-requests' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"amount": 149.00,
"currency": "EUR",
"title": "John Smith",
"orderId": "ORD-2026-1045",
"description": "Order ORD-2026-1045",
"redirectUrl": "https://yourshop.com/payment-success",
"customerEmail": "john@example.com",
"discount": 5
}'
async function createPayLink({ amount, currency, orderId, title, customerEmail }) {
const response = 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,
currency,
orderId,
title,
customerEmail,
description: `Order ${orderId}`,
redirectUrl: `${process.env.APP_URL}/orders/${orderId}/success`,
}),
}
);
if (!response.ok) throw new Error(`Coinsnap ${response.status}`);
const { id, url } = await response.json();
return { payLinkId: id, payLinkUrl: url };
}
<?php
function createPayLink(array $params): array {
$storeId = getenv('COINSNAP_STORE_ID');
$ch = curl_init("https://app.coinsnap.io/api/v1/stores/{$storeId}/payment-requests");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'x-api-key: ' . getenv('COINSNAP_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($params),
]);
$response = json_decode(curl_exec($ch), true);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code >= 400) {
throw new RuntimeException('Coinsnap error: ' . $code);
}
return $response; // ['id' => ..., 'url' => ...]
}
// Usage
$payLink = createPayLink([
'amount' => 149.00,
'currency' => 'EUR',
'orderId' => 'ORD-2026-1045',
'title' => 'John Smith',
'description' => 'Order ORD-2026-1045',
'customerEmail' => 'john@example.com',
'redirectUrl' => 'https://yourshop.com/payment-success',
]);
// Store $payLink['id'] and $payLink['url'] against your order
import os
import requests
def create_pay_link(amount, currency, order_id, title, customer_email=None):
store_id = os.environ['COINSNAP_STORE_ID']
api_key = os.environ['COINSNAP_API_KEY']
payload = {
'amount': amount,
'currency': currency,
'orderId': order_id,
'title': title,
'description': f'Order {order_id}',
'redirectUrl': f'{os.environ["APP_URL"]}/orders/{order_id}/success',
}
if customer_email:
payload['customerEmail'] = customer_email
response = requests.post(
f'https://app.coinsnap.io/api/v1/stores/{store_id}/payment-requests',
headers={
'x-api-key': api_key,
'Content-Type': 'application/json',
},
json=payload,
)
response.raise_for_status()
return response.json() # { 'id': ..., 'url': ... }
Minimal request
The backend currently requires amount and title. currency is optional.
{
"amount": 149.00,
"title": "John Smith"
}
Bitcoin discount
To offer a percentage discount to customers who pay with Bitcoin, include the discount field:
{
"amount": 149.00,
"currency": "EUR",
"orderId": "ORD-2026-1045",
"discount": 5
}
The customer sees the discounted Bitcoin amount on the payment page. The original fiat amount is unchanged in your system.
Best practices
- Always pass
orderId— it's your reconciliation key and appears in every webhook event - Store the returned
id— you'll need it to check status or update the pay link via API - Use a meaningful
description— the customer sees it on the payment page - Set
expiryDatefor time-limited invoices (e.g. quotes that expire) - Set
redirectUrlto send the customer back to your site after payment
API reference
See API Reference → Create Pay Link for the full endpoint specification.