받을 수 있는 자산
Lightning은 BTC만 받으며 스테이블코인이나 온체인 주소 전송은 받지 않아요. 요청마다 금액, 결제 해시, 만료 시간이 있고 고객은 청구서 전액을 내야 해요.
Bitcoin 온체인 결제스토어 설정
설정 → 체인 연결에서 HTTPS LND 또는 WSS NWC를 추가하고 매장에서 활성화하세요. 공개 접근 가능한 엔드포인트가 필요하며 LAN 전용이나 Tor 전용 주소는 직접 연결할 수 없어요.
인증 정보와 자금 보관
제한된 수신 권한만 사용하고 LND 관리자나 송금 macaroon은 쓰지 마세요. NWC는 연결 규격일 뿐 보관 방식을 보장하지 않아요. 누가 키를 보관하는지 확인하세요.
결제가 도착하는 곳
QR에는 Bitcoin 주소가 아닌 BOLT11 Lightning 청구서가 있어요. 온체인으로 결제하지 마세요. 만료되면 새 청구서를 만들어야 하며 기한만 연장할 수 없어요.
결제는 언제 완료되나요?
Wholly Crypto는 연결된 지갑이 보고한 정산을 검증해요. 열린 청구서나 보류된 HTLC는 결제가 아니에요. Lightning에는 블록 확인이나 공개 거래 탐색기 링크가 없어요.
준비되면 자금을 옮기세요
송금, 채널 유동성, 백업은 외부 지갑이나 노드에서 관리하세요. 온체인 스윕으로 Lightning 잔액을 옮길 수 없고 프로젝트 지갑 내보내기는 외부 지갑의 백업이 아니에요.
Lightning 지갑 가이드결제 문제 해결
경로를 찾지 못하면 수신 유동성, 지갑 연결과 만료 시간을 확인하세요. 정상 API가 경로를 보장하지 않아요. 결과가 불확실하면 정산을 확인한 뒤 재시도를 요청하세요.
수수료와 검증
기본 처리 수수료는 청구서 법정화폐 금액의 1%이며 별도 크레딧에서 차감돼요. 계정에 지정된 요율이 적용되고 네트워크와 서버 비용은 별도예요.
공개 제공자는 장애나 요청 제한이 생길 수 있어요. 거래 제출이나 리디렉션만으로 결제를 확인할 수는 없어요. 검증된 청구서 상태와 서명된 알림을 사용하세요.
처리 크레딧 API, IPN 및 웹훅환율 계산기
금액 환산
예상치이며 결제 견적은 아니에요. 네트워크 수수료, 거래소 수수료, 판매자 스프레드는 포함하지 않아요.
환율은 어디서 가져오나요?
암호화폐 예상치는 캐시된 Kraken 공개 가격과 가능한 경우 Binance 가격을 사용해요. 일부 Binance 가격은 USDT를 USD 기준으로 써요. 법정화폐 환율은 Frankfurter의 일일 참고 환율이며 실시간 거래 호가는 아니에요.
스냅샷은 자동 갱신돼요. 결과 아래에서 출처 날짜를 확인하세요. 입력한 금액은 브라우저 안에만 남아요. 자산 목록에 있다고 결제 지원을 보장하지는 않아요.
API로 청구서 만들기
예제는 서버에서 실행하세요. API 호스트, 프로젝트 ID, 매장 ID를 바꾸고 인증 정보는 비공개로 유지하세요. 금액은 십진 문자열이에요.
먼저 매장에서 방법을 활성화하세요. 선택은 활성 방법만 좁히며 자산을 추가하지 않아요. 일치 항목이 없으면 매장 기본값이 적용돼요. 결제 화면을 열기 전 반환된 방법을 확인하세요.
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new invoice.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: order-1042-attempt-1' \
--header 'Content-Type: application/json' \
--data-raw '{
"amount": "25.00",
"currency": "EUR",
"order_id": "order-1042",
"payment_methods": [
{
"chain_slug": "bitcoin",
"payment_rail": "lightning"
}
]
}'// Node.js 18+ · run on your server, never in browser code.
const token = process.env.WHOLLY_TOKEN;
if (!token) throw new Error("Set WHOLLY_TOKEN");
// Keep this key and the exact body for retries; use a new key for each new invoice.
const body = `{
"amount": "25.00",
"currency": "EUR",
"order_id": "order-1042",
"payment_methods": [
{
"chain_slug": "bitcoin",
"payment_rail": "lightning"
}
]
}`;
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "order-1042-attempt-1",
"Content-Type": "application/json"
},
body,
redirect: "error",
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
console.log(await response.json());<?php
// PHP 8+ with the cURL extension; run on your server.
$token = getenv('WHOLLY_TOKEN');
if (!$token) { throw new RuntimeException('Set WHOLLY_TOKEN'); }
// Keep this key and the exact body for retries; use a new key for each new invoice.
$body = <<<'JSON'
{
"amount": "25.00",
"currency": "EUR",
"order_id": "order-1042",
"payment_methods": [
{
"chain_slug": "bitcoin",
"payment_rail": "lightning"
}
]
}
JSON;
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: order-1042-attempt-1", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
if ($status < 200 || $status >= 300) { throw new RuntimeException("HTTP $status: $response"); }
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));# Python 3 · standard library; run on your server.
import json
import os
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
# Keep this key and the exact body for retries; use a new key for each new invoice.
headers = {
"Idempotency-Key": "order-1042-attempt-1",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"amount": "25.00",
"currency": "EUR",
"order_id": "order-1042",
"payment_methods": [
{
"chain_slug": "bitcoin",
"payment_rail": "lightning"
}
]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices",
method="POST", headers=headers, data=body)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
print(json.load(response))