TÀI LIỆU DÀNH CHO NHÀ PHÁT TRIỂN
Tài liệu API
Tích hợp hóa đơn, trang thanh toán và thông báo thanh toán.
Kết quả tìm kiếm
Không có kết quả. Thử tên endpoint, trường hoặc hướng dẫn.
Bắt đầu nhanh
Tạo hóa đơn đầu tiên.
- Chuẩn bị cửa hàng
Bật phương thức thanh toán, cấu hình nhà cung cấp và sao lưu ví dự án.
- Tạo thông tin xác thực API
Trong Cài đặt → Truy cập API của bảng điều khiển, chọn đọc/ghi và gán dự án.
- Gửi yêu cầu
Dùng máy chủ API của bạn và sao chép ID dự án và cửa hàng. Gửi số tiền thập phân dưới dạng chuỗi.
- Mở trang thanh toán
Chuyển hướng đến
links.checkouttừ phản hồi. Xác minh quyết toán trước khi hoàn tất đơn hàng.
: "${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": "49.90",
"currency": "USD",
"order_id": "order-1042",
"exchange_rate_spread_percent": "0.5"
}'// 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": "49.90",
"currency": "USD",
"order_id": "order-1042",
"exchange_rate_spread_percent": "0.5"
}`;
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": "49.90",
"currency": "USD",
"order_id": "order-1042",
"exchange_rate_spread_percent": "0.5"
}
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": "49.90",
"currency": "USD",
"order_id": "order-1042",
"exchange_rate_spread_percent": "0.5"
}""".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))Ví dụ dùng giá trị giữ chỗ và không gửi yêu cầu từ trang này. Xem mọi trường hóa đơn và định dạng phản hồi →
ID dự án & cửa hàng
Tìm YOUR_PROJECT_ID và YOUR_STORE_ID ở đâu.
Dùng UUID từ bảng điều khiển, không dùng tên dự án hay cửa hàng hoặc mã định danh dễ đọc của chúng.
| Giá trị giữ chỗ | Nơi tìm | Dùng cho |
|---|---|---|
| YOUR_PROJECT_ID | Dự án → Cài đặt → ID API → ID API dự án → Sao chép. Cũng hiển thị trong thẻ Cơ bản của cửa hàng. | Yêu cầu cấp dự án và cấp cửa hàng. |
| YOUR_STORE_ID | Dự án → Cửa hàng → chọn cửa hàng → Cơ bản → ID API → ID API cửa hàng → Sao chép. | Yêu cầu tạo hóa đơn và phương thức thanh toán của cửa hàng. |
- Tạo hóa đơn cần cả hai ID, kể cả với cửa hàng mặc định. Cửa hàng phải thuộc dự án đó và thông tin xác thực API phải có quyền truy cập dự án.
- Tạo, liệt kê, xem chi tiết hóa đơn và trang thanh toán trả về invoice_id: cùng UUID được gửi trong IPN/webhook. Dùng nó trong đường dẫn hóa đơn, không dùng id nội bộ hay order_id. Từ merchant 4.0.0, trường phản hồi public_id cũ đã bị bỏ; hãy cập nhật tích hợp trước khi nâng cấp.
- REST API không cung cấp tuyến liệt kê dự án/cửa hàng. Sao chép ID trong bảng điều khiển, hoặc dùng công cụ MCP list_projects và list_stores có giới hạn phạm vi trong merchant 5.0.0+.
- Cửa hàng → Cơ bản → Tên miền cửa hàng chọn tên máy chủ đang hoạt động cho nhà bán hàng, thanh toán và API. Liên kết thanh toán trả về và liên kết callback mới ưu tiên cửa hàng đó, rồi cửa hàng mặc định, rồi mặc định hệ thống. Tên đã ngừng dùng hoặc chưa kích hoạt không bao giờ được chọn. Cấu hình SDK bằng tên máy chủ API ưu tiên; đổi tùy chọn ưu tiên không chuyển hướng các bí danh đang hoạt động khác.
Xác thực & phạm vi
Giữ thông tin xác thực trên máy chủ của bạn và chỉ cấp quyền cần thiết.
| Máy chủ mặc định | Mục đích |
|---|---|
| merchant.example.com | Bảng điều khiển nhà bán hàng và Cài đặt |
| pay.example.com | Trang thanh toán của khách hàng |
| api.example.com | Yêu cầu API nhà bán hàng |
Thay example.com bằng tên miền của bạn. Bản cài đặt hiện có giữ tên đã cấu hình; quản lý bí danh trong Cài đặt → Hệ thống.
Authorization: Bearer YOUR_MERCHANT_API_TOKEN| Cài đặt | Cách hoạt động |
|---|---|
| Cấp truy cập | Thông tin xác thực chỉ đọc có thể liệt kê và truy xuất. Thông tin xác thực đọc/ghi còn có thể tạo hóa đơn và cập nhật chính sách tài sản được ghi trong tài liệu. |
| Dự án | Gán những dự án mà thông tin xác thực được phép truy cập. ID cửa hàng và hóa đơn phải thuộc dự án đã gán. |
| Giới hạn IP | Có thể chỉ cho phép địa chỉ IPv4 hoặc IPv6 công khai đầu ra chính xác trong Cài đặt → Truy cập API. |
| Lưu trữ thông tin xác thực | Giữ token trong cấu hình backend. Không bao giờ đưa thông tin xác thực bearer vào trình duyệt hoặc liên kết thanh toán. |
Các tuyến thanh toán công khai dùng ID công khai của hóa đơn và chỉ cung cấp dữ liệu an toàn cho trang thanh toán. Phiên bảng điều khiển và quyền quản trị tách biệt với thông tin xác thực API nhà bán hàng.
Tài sản & ví
Chọn phương thức thanh toán độc lập cho từng cửa hàng.
- Đọc tài sản thanh toán của dự án và trạng thái sẵn sàng của chúng.
- Bật chuỗi gốc và cấu hình ví cùng nhà cung cấp.
- Duyệt token ứng viên và xác minh hợp đồng hoặc mint trước khi bật token.
- Chọn danh sách có thứ tự của cửa hàng về phương thức thanh toán. Hóa đơn mới dùng các lựa chọn đã sẵn sàng.
Token dùng chung ví với chuỗi gốc của chúng. Số dư ví trả về số tiền chính xác theo đơn vị nhỏ nhất và giá trị tiền pháp định tham khảo. Dùng các trường trạng thái sẵn sàng được trả về để xác định phương thức nào có thể nhận thanh toán.
Token ERC-20 đã xác minh dùng các mạng EVM được hỗ trợ; token SPL đã xác minh dùng Solana. Phương thức thanh toán bằng đồng gốc có trên 30 mạng được tích hợp. Monero dùng kết nối ví chỉ xem bên ngoài gắn với dự án.
API nhận tiền và phạm vi hỗ trợ đồng gốc/token
| Hệ thống thanh toán | Hỗ trợ | Bằng chứng | Yêu cầu |
|---|---|---|---|
| Hệ thống thanh toán đồng gốc | được hỗ trợ | Quét giao dịch | BTC, SOL, ETH (Ethereum/Base/Arbitrum/OP), BNB, HYPE, AVAX và POL; đầu ra Bitcoin, giao dịch/biên nhận EVM chính tắc và chuyển khoản Solana đã phân tích cung cấp bằng chứng cho hóa đơn. |
| Hệ thống thanh toán token ERC-20 | được hỗ trợ | Quét giao dịch | Ethereum, Base, BNB Chain, HyperEVM, Avalanche, Polygon, Arbitrum và Optimism cần xác minh trên chuỗi; nhật ký Transfer đã lập chỉ mục dùng để xác định khoản thanh toán thuộc về đâu. |
| Hệ thống thanh toán token SPL | được hỗ trợ | Quét giao dịch | Ứng viên Solana cần xác minh mainnet và mint; chênh lệch số dư token chính xác trong giao dịch đã phân tích dùng để xác định khoản thanh toán thuộc về đâu. |
| Các hệ thống thanh toán đồng gốc UTXO bổ sung | được hỗ trợ | Quét giao dịch | BCH/LTC/DOGE dùng Esplora; BCH/DOGE cũng chấp nhận Bitcore, LTC/DOGE/DASH chấp nhận BlockCypher, Dash chấp nhận Insight và ZEC minh bạch chấp nhận zcash-explorer. Tất cả cũng chấp nhận khối node-rpc tương thích Core được lưu giữ đầy đủ. Chế độ thô cần 1–48 xác nhận, không dùng phát hiện trong mempool. Không hỗ trợ Zcash được che chắn. |
| Hệ thống thanh toán đồng gốc dựa trên tài khoản đã lập chỉ mục | được hỗ trợ | Quét giao dịch | TRON dùng tron-indexer hoặc node-rpc đã solidified; XRP dùng xrpl-jsonrpc; Stellar dùng stellar-horizon hoặc sổ cái Stellar node-rpc được lưu giữ; Cosmos Hub dùng cometbft-jsonrpc; Algorand dùng algorand-indexer hoặc algod node-rpc; Hedera cần hedera-mirror, không phải relay EVM. |
| Hệ thống thanh toán đồng gốc trên sổ cái | được hỗ trợ | Quét giao dịch | Aptos dùng aptos-rest; Sui dùng sui-graphql; NEAR dùng near-jsonrpc; Kaspa dùng kaspa-rest. Polkadot Asset Hub chấp nhận substrate-rest hoặc node-rpc đã hoàn tất có nhận biết metadata; Tezos chấp nhận tezos-tzkt hoặc thao tác Octez node-rpc đầy đủ. Chỉ nhận đồng gốc; hóa đơn cũ cần dữ liệu lưu trữ lịch sử. |
| Hệ thống thanh toán đồng gốc Cardano và TON | được hỗ trợ | Quét giao dịch | Cardano cần cardano-koios và TON cần toncenter-v3. Tag XRP, memo ID Stellar và bình luận hóa đơn TON được trả về dưới dạng destination_tag và phải được gửi chính xác. |
| Tính toàn vẹn của quyết toán | được hỗ trợ | Xác minh độc lập | Mặc định, quyết toán cuối cùng cần hai nhà cung cấp độc lập thống nhất về giao dịch/sự kiện chính xác, số tiền, khối hoặc slot chính tắc và tính hoàn tất. Cửa sổ quét thô và EVM dùng chung cũng xác minh phạm vi bao phủ đầy đủ. Quản trị viên có thể chủ động chọn một nhà cung cấp tin cậy cho một chuỗi; việc này bỏ kiểm tra chéo độc lập, không bỏ kiểm tra danh tính, tính đầy đủ hay tính hoàn tất. |
| Hệ thống thanh toán đồng gốc Monero | được hỗ trợ | RPC ví chỉ xem gắn với dự án | Một wallet-RPC chỉ xem chuyên dụng bên ngoài, đặt sau cổng HTTPS chỉ cho phép các phương thức đã duyệt, tạo địa chỉ phụ của account-0. Ngưỡng daemon mainnet được cấu hình (mặc định 2 nguồn độc lập, tùy chọn 1) cung cấp bằng chứng quyết toán. --restricted-rpc gốc không tương thích với create_address; người vận hành phải xác nhận rõ rằng đã sao lưu ví và ví không có khóa chi tiêu, còn không có dữ liệu khóa nào được gửi tới Wholly Crypto. |
Số dư sàn giao dịch và lựa chọn gom tiền về ví hoặc sàn theo từng tài sản có trong bảng điều khiển, không có qua API v1 công khai. Xem thiết lập sàn giao dịch.
Vòng đời hóa đơn
Bằng chứng thanh toán, quyết toán và hoàn tất đơn hàng.
| Trạng thái | Ý nghĩa |
|---|---|
| new | Đang chờ thanh toán |
| processing | Đã quan sát thấy thanh toán; đang chờ đủ số tiền được chấp nhận hoặc tính hoàn tất |
| settled | Được chấp nhận theo chính sách quyết toán hóa đơn hoặc theo cách thủ công |
| expired | Đã qua hạn; việc theo dõi thanh toán muộn có thể tiếp tục |
| invalid | Không thể tự động chấp nhận thanh toán |
| cancelled | Đã hủy; chỉ thao tác đối soát rõ ràng mới có thể mở lại |
amount_status bản ghi none, partial, paid hoặc overpaid. timing_status phân biệt thanh toán đúng hạn và muộn. Quy tắc cửa hàng quyết định số xác nhận cần thiết và dung sai thiếu tiền được chấp nhận.
Dùng giá trị của hóa đơn là invoice_id với tuyến chi tiết hóa đơn. Chỉ chuyển hướng từ trang thanh toán không phải bằng chứng quyết toán. Xem xét ngoại lệ qua đối soát.
Thử lại an toàn
Tạo hóa đơn cần Idempotency-Key. Sau khi hết thời gian chờ, thử lại bằng cùng thông tin xác thực, khóa và nội dung yêu cầu chính xác. Chỉ dùng khóa mới cho hóa đơn mới.
Quét thanh toán EVM
Cơ chế phát hiện khối đồng gốc và ERC-20 dùng chung nhóm hóa đơn gần đây riêng với công việc truy quét lịch sử cũ. Mỗi hóa đơn giữ con trỏ lịch sử bền vững. Truy vấn token dùng tối đa 100 khối mỗi yêu cầu và thu hẹp với nhà cung cấp có giới hạn chặt hơn. Mặc định, hai nhà cung cấp độc lập xác minh mỗi cửa sổ. Cài đặt → Kết nối chuỗi → Chi tiết cho phép chọn một nguồn tin cậy cho chuỗi mà không có kiểm tra chéo độc lập; vẫn kiểm tra giao dịch chính tắc, số tiền và xác nhận. Chi tiết kết nối phân biệt độ trễ máy quét, giới hạn lịch sử và thời gian chờ hạn mức với tình trạng cơ bản của nút. Năng lực RPC công khai không được bảo đảm.
IPN & webhook
Nhận và xác minh sự kiện thanh toán.
IPN nhận mọi sự kiện hóa đơn được tạo tại ipn_url có hiệu lực của hóa đơn. Webhook chỉ nhận sự kiện được chọn cho từng endpoint cửa hàng đang bật. Cả hai POST cùng bản chụp JSON; chúng độc lập nên bật cả hai có thể thông báo cho ứng dụng hai lần.
Đặt ipn_url khi tạo hóa đơn, hoặc kế thừa mặc định của cửa hàng. IPN dùng bí mật Cửa hàng → IPN ; mỗi Cửa hàng → Webhook endpoint có bí mật riêng. Cả hai đều không phải khóa API của bạn.
Khi nào tôi nên hoàn tất đơn hàng?
Để xử lý theo sự kiện, dùng event_type = invoice.settled cùng status = settled để kích hoạt kiểm tra đơn hàng. Xác minh hóa đơn hiện tại và chỉ hoàn tất mỗi đơn hàng một lần.
status là trạng thái hóa đơn khi sự kiện được tạo. event_type cho biết điều gì đã xảy ra. payment.received có thể mang processing hoặc settled; nó không có nghĩa là có khoản thanh toán thứ hai và không phải tín hiệu độc lập để hoàn tất đơn hàng.
Những sự kiện và trạng thái nào được gửi?
| Sự kiện trong cài đặt/lịch sử | Trạng thái trong nội dung | Ý nghĩa |
|---|---|---|
| invoice.created | new | Hóa đơn đã tạo và đang chờ thanh toán. Cũng dùng khi thao tác mở lại có kiểm soát đưa hóa đơn về new. |
| payment.received | Resulting invoice status | Đã ghi nhận thanh toán hoặc số tiền nhận tăng lên. Thường là processing hoặc settled; riêng sự kiện này không phải bằng chứng quyết toán. |
| invoice.processing | processing | Đã phát hiện thanh toán, nhưng chưa đạt số tiền được chấp nhận hoặc mức hoàn tất cần thiết. Bao gồm cả thanh toán một phần. |
| invoice.settled | settled | Đã đáp ứng chính sách quyết toán hoặc được chấp nhận thủ công. Kiểm tra resolution và đơn hàng trước khi hoàn tất. |
| invoice.expired | expired | Đã qua hạn thanh toán. Thanh toán muộn vẫn có thể thay đổi trạng thái khi việc theo dõi tiếp tục. |
| invoice.invalid | invalid | Không thể tự động chấp nhận, bằng chứng thanh toán đã mất hoặc nhà bán hàng đã từ chối. Hãy xem xét hóa đơn. |
| invoice.cancelled | cancelled | Hóa đơn đã hủy. Không hoàn tất đơn hàng; hủy hóa đơn không hoàn lại khoản thanh toán trên chuỗi. |
Vì sao Ethereum và Solana có thể gửi luồng sự kiện khác nhau
Xác nhận đến sau (ví dụ Ethereum)
| Trình tự | event_type | status |
|---|---|---|
| 1 | invoice.created | new |
| 2 | payment.received | processing |
| 2 | invoice.processing | processing |
| 3 | invoice.settled | settled |
Đã hoàn tất khi được phát hiện (ví dụ Solana)
| Trình tự | event_type | status |
|---|---|---|
| 1 | invoice.created | new |
| 2 | payment.received | settled |
| 2 | invoice.settled | settled |
Các ví dụ này thể hiện việc tạo sự kiện, không bảo đảm thứ tự gửi đến. Cả hai luồng đều có thể xảy ra trên chuỗi khác tùy thời điểm phát hiện và chính sách quyết toán. Không yêu cầu phải có sự kiện processing trước settled.
Hoàn tất một lần: ví dụ bên nhận và chống trùng lặp
| Cách tiếp cận | Cách xử lý |
|---|---|
| Bên nhận theo sự kiện | Giữ riêng từng sự kiện theo event_id đã ký, rồi chọn invoice.settled với status = settled. Không bỏ sự kiện này vì payment.received có cùng sequence đã đến trước. |
| Hộp nhận trạng thái đơn hàng của SDK | Các ví dụ bên nhận PHP, Python và Node được cung cấp gộp theo project + invoice_id + sequence. Xử lý trạng thái đã lưu bất kể event_type, lấy hóa đơn hiện tại và hoàn tất một lần nếu settled. Không thêm bộ lọc chỉ nhận invoice.settled sau bước gộp này. |
Lần thử lại giữ nguyên event_id và nội dung gốc. Các sự kiện khác nhau có thể cùng sequence nhưng khác event_id. Loại bỏ lần gửi trùng theo event_id đã ký khi xử lý theo sự kiện; đồng thời bảo vệ riêng việc hoàn tất bằng bản cài đặt/dự án đã cấu hình + invoice_id và đơn hàng. Quyết toán lại về sau không được ghi có cho đơn hàng hai lần.
HTTP receiver:
Verify raw-body signature, timestamp and configured project/store scope.
Save to a durable inbox; deduplicate the signed event_id.
Return HTTP 2xx only after persistence succeeds.
Event-based background worker:
Other events go to status/reconciliation handling, not fulfilment.
Continue here only for event_type = invoice.settled and status = settled.
Fetch the current invoice from your configured API origin.
Check settled status, project/store, order, amount, currency and review policy.
In one database transaction:
Lock the order and check the scoped invoice has not been fulfilled.
Credit/complete once and save the fulfilment record.
Queue any external fulfilment with the same business idempotency key.
SDK order-state worker:
Use the same current-invoice checks and fulfil-once transaction.
Do not filter event_type after collapsing events by invoice revision.Mã giả, không phải mã bên nhận dùng ngay.
Mọi trạng thái hóa đơn và ngoại lệ thanh toán
| Trường | Giá trị | Ý nghĩa |
|---|---|---|
| status | new, processing, settled, expired, invalid, cancelled | Trạng thái hóa đơn khi tạo sự kiện; không nhất thiết là trạng thái hiện tại lúc gửi đến. |
| amount_status | none, partial, paid, overpaid | Số tiền đã nhận, bao gồm dung sai được chấp nhận. paid không có nghĩa là xác nhận đã hoàn tất. |
| timing_status | on_time, late | Thanh toán có đáp ứng hạn hóa đơn hay không. |
| resolution | automatic, manually_settled, manually_invalidated | Kết quả được quyết định bởi quy tắc thông thường hay chấp nhận/từ chối thủ công. |
| requires_review | false, true | Gợi ý ngoại lệ, không phải trạng thái hóa đơn khác hay quyền tự động hoàn tất/hoàn tiền. |
| Tình huống | Cách xử lý |
|---|---|
| Thanh toán thiếu / dung sai | Theo quy tắc tự động, partial không được quyết toán. paid có thể bao gồm phần thiếu được chấp nhận, nhưng vẫn cần tính hoàn tất. Dùng trạng thái hóa đơn, không chỉ so sánh số tiền. |
| Thanh toán thừa | overpaid có thể đi cùng settled và requires_review = true. Áp dụng chính sách thanh toán thừa; không bao giờ ghi có đơn hàng hai lần hoặc tự động hoàn tiền về địa chỉ chưa xác minh. |
| Thanh toán muộn | expired có thể thay đổi về sau khi việc theo dõi tiếp tục. timing_status = late đánh dấu cần xem xét; không tự động mở lại hay giao đơn hàng đã hủy. |
| Chấp nhận thủ công | invoice.settled có thể có resolution = manually_settled mà không có tiền trên chuỗi đủ điều kiện. Quyết định xem tích hợp của bạn có chấp nhận ghi đè này không; các trường tóm tắt thanh toán có thể là null. |
| Tái tổ chức chuỗi / vô hiệu hóa | Bản sửa đổi mới hơn có thể vô hiệu hóa bằng chứng thanh toán trước đó. Lấy lại trạng thái hiện tại và xử lý đảo ngược qua đối soát. Đừng bỏ qua chỉ vì đơn hàng từng được quyết toán. |
| Không xác nhận / số tiền bằng không | Quyết toán không xác nhận có thể xảy ra ngay khi phát hiện và có rủi ro tái tổ chức chuỗi. Hóa đơn số tiền bằng không được cho phép rõ ràng sẽ quyết toán mà không có thanh toán. Cả hai đều không cần sự kiện payment.received trước. |
Dùng status = settled để hoàn tất đơn hàng, không dùng amount_status = paid hay chuyển hướng từ trang thanh toán. Khi yêu cầu không xác nhận, quyết toán có thể xảy ra ngay lúc phát hiện; điều này có rủi ro tái tổ chức chuỗi.
Thanh toán thiếu là amount_status = partial; thanh toán thừa là overpaid. paid nghĩa là đã nhận mức tối thiểu được chấp nhận, gồm dung sai thiếu tiền của hóa đơn. Đây là trạng thái số tiền, không phải trạng thái hóa đơn. late là timing_status, không phải sự kiện riêng.
Luồng thường gặp là new → processing → settled, nhưng có thể bỏ qua trạng thái trung gian. Hóa đơn số tiền bằng không được cho phép rõ ràng sẽ quyết toán mà không có thanh toán và giữ amount_status = none. Chấp nhận thủ công được đánh dấu manually_settled.
Callback là bản chụp bất biến, không phải phản hồi trạng thái trực tiếp. Chúng có thể đến muộn, sai thứ tự hoặc nhiều lần. Sự kiện thanh toán và trạng thái có thể dùng chung sequence hóa đơn và các trường trạng thái hóa đơn, nhưng khác giá trị event_id đã ký và event_type. Số xác nhận không bảo đảm tạo callback cho mỗi khối.
Những gì bạn nhận được
{
"invoice_id": "11111111-2222-4333-8444-555555555555",
"status": "settled",
"amount_status": "paid",
"timing_status": "on_time",
"resolution": "automatic",
"sequence": 3,
"amount": "49.9",
"currency": "EUR",
"order_id": "order-1042",
"payload_version": 2,
"event_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
"event_type": "invoice.settled",
"occurred_at": "2026-09-14T12:05:00Z",
"project_id": "11111111-1111-4111-8111-111111111111",
"store_id": "22222222-2222-4222-8222-222222222222",
"description": "Annual plan",
"email": "ada@example.test",
"customer": {
"firstname": "Ada",
"lastname": "Lovelace",
"countryiso2": "GB"
},
"metadata": {
"firstname": "Ada",
"lastname": "Lovelace",
"countryiso2": "GB",
"cart_id": "cart-681"
},
"created_at": "2026-09-14T12:00:00Z",
"updated_at": "2026-09-14T12:05:00Z",
"expires_at": "2026-09-14T12:15:00Z",
"monitoring_expires_at": "2026-09-21T12:15:00Z",
"settled_at": "2026-09-14T12:05:00Z",
"paid_chain": "ethereum",
"paid_asset": "USDC",
"paid_asset_amount": "58.17342",
"paid_asset_amount_received": "58.17342",
"paid_payment_method_id": "33333333-3333-4333-8333-333333333333",
"settlement_exchange_rate": {
"rate": "1.17",
"units": "asset_per_invoice_currency",
"currency": "EUR",
"symbol": "USDC",
"observed_at": "2026-09-14T12:05:00Z",
"as_of": "2026-09-14T12:04:30Z",
"pricing_provider": "kraken",
"asset_provider": "kraken",
"pricing_fetched_at": "2026-09-14T12:04:30Z",
"asset_fetched_at": "2026-09-14T12:04:30Z",
"stale": false,
"is_fixed": false,
"reference_currency": "USD",
"uses_reference_proxy": false
},
"cancelled_at": null,
"exchange_rate_spread_percent": "0.5",
"underpayment_tolerance_percent": "1",
"reason_code": "payment_confirmed",
"requires_review": false,
"links": {
"checkout": "https://pay.example.com/invoice/11111111-2222-4333-8444-555555555555",
"invoice": "https://api.example.com/v1/projects/11111111-1111-4111-8111-111111111111/invoices/11111111-2222-4333-8444-555555555555",
"payments": "https://api.example.com/v1/projects/11111111-1111-4111-8111-111111111111/invoices/11111111-2222-4333-8444-555555555555/payments"
},
"payment_info": {
"active_payment_method_id": "33333333-3333-4333-8333-333333333333",
"method_count": 1,
"methods_truncated": false,
"methods": [
{
"payment_method_id": "33333333-3333-4333-8333-333333333333",
"payment_rail": "onchain",
"chain_slug": "ethereum",
"network": "mainnet",
"caip_network_id": "eip155:1",
"asset_id": "44444444-4444-4444-8444-444444444444",
"asset_key": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"caip_asset_id": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"asset_name": "USD Coin",
"symbol": "USDC",
"asset_kind": "token",
"asset_decimals": 6,
"contract_address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"token_standard": "erc20",
"destination_address": "0x1111111111111111111111111111111111111111",
"destination_tag": null,
"status": "paid",
"amounts": {
"expected_amount": "58.17342",
"expected_amount_atomic": "58173420",
"received_amount": "58.17342",
"received_amount_atomic": "58173420",
"confirmed_amount": "58.17342",
"confirmed_amount_atomic": "58173420",
"unconfirmed_amount": "0",
"unconfirmed_amount_atomic": "0",
"minimum_payment_amount": "57.591686",
"minimum_payment_amount_atomic": "57591686",
"remaining_amount": "0",
"remaining_amount_atomic": "0",
"remaining_to_full_amount": "0",
"remaining_to_full_amount_atomic": "0",
"overpaid_amount": "0",
"overpaid_amount_atomic": "0"
},
"acceptance": {
"finality_mode": "confirmations",
"required_confirmations": 2,
"observed_confirmations": 2,
"underpayment_tolerance_percent": "1"
},
"quote": {
"effective_rate": "1.1658",
"reference_rate": "1.16",
"units": "asset_per_invoice_currency",
"currency": "EUR",
"symbol": "USDC",
"exchange_rate_spread_percent": "0.5",
"quote_expires_at": "2026-09-14T12:15:00Z",
"provenance_available": true,
"rounding": "up",
"unrounded_payment_amount": "58.17342",
"rounding_adjustment": "0",
"pricing_provider": "kraken",
"asset_provider": "kraken",
"pricing_fetched_at": "2026-09-14T11:59:30Z",
"asset_fetched_at": "2026-09-14T11:59:30Z"
},
"market_rate_at_event": {
"rate": "1.17",
"units": "asset_per_invoice_currency",
"currency": "EUR",
"symbol": "USDC",
"observed_at": "2026-09-14T12:05:00Z",
"pricing_provider": "kraken",
"asset_provider": "kraken",
"pricing_fetched_at": "2026-09-14T12:04:30Z",
"asset_fetched_at": "2026-09-14T12:04:30Z",
"as_of": "2026-09-14T12:04:30Z",
"stale": false,
"is_fixed": false,
"reference_currency": "USD",
"uses_reference_proxy": false
},
"payment_count": 1,
"payments_truncated": false,
"payments": [
{
"payment_id": "55555555-5555-4555-8555-555555555555",
"payment_method_id": "33333333-3333-4333-8333-333333333333",
"transaction_id": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"payment_hash": null,
"event_index": 0,
"payment_rail": "onchain",
"chain_slug": "ethereum",
"network": "mainnet",
"asset_id": "44444444-4444-4444-8444-444444444444",
"asset_key": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"caip_asset_id": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"symbol": "USDC",
"asset_decimals": 6,
"amount": "58.17342",
"amount_atomic": "58173420",
"status": "final",
"counts_towards_received": true,
"confirmations": 2,
"block_height": 26000000,
"observed_at": "2026-09-14T12:04:30Z",
"chain_time": "2026-09-14T12:04:20Z",
"finalized_at": "2026-09-14T12:05:00Z",
"explorer_name": "Etherscan",
"explorer_url": "https://etherscan.io/tx/0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
],
"links": {
"payments": "https://api.example.com/v1/projects/11111111-1111-4111-8111-111111111111/invoices/11111111-2222-4333-8444-555555555555/payments?payment_method_id=33333333-3333-4333-8333-333333333333"
}
}
]
}
}amount là tổng tiền hóa đơn ban đầu. payment_info mô tả các khoản chuyển tiền mã hóa đã quan sát, số tiền còn thiếu và tỷ giá đã khóa. Phiên bản 2 còn ký tên sự kiện, ID sự kiện và phạm vi dự án/cửa hàng.
Mọi trường callback và dữ liệu hóa đơn bổ sung
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
| invoice_id | UUID | UUID công khai của hóa đơn, dùng bởi tuyến chi tiết hóa đơn có xác thực |
| status | string | Trạng thái hóa đơn tại thời điểm chụp: new, processing, settled, expired, invalid, cancelled |
| amount_status | string | none, partial, paid hoặc overpaid; paid bao gồm dung sai thiếu tiền được chấp nhận, không phải tính hoàn tất của xác nhận |
| timing_status | string | on_time hoặc late |
| resolution | string | automatic, manually_settled hoặc manually_invalidated |
| sequence | integer | Phiên bản sửa đổi hóa đơn tăng dần; các sự kiện khác nhau có thể dùng chung một phiên bản. So sánh mà không mất độ chính xác số nguyên |
| amount | decimal string | Tổng tiền hóa đơn ban đầu, không phải số tiền mã hóa đã nhận; giữ độ chính xác thập phân |
| currency | string | Loại tiền của amount, ví dụ EUR cho hóa đơn EUR được thanh toán bằng USDC |
| order_id | string | null | Mã tham chiếu đơn hàng của nhà bán hàng |
| payload_version | integer | 2 cho sự kiện mới tạo từ 4.1.0+; không có trên sự kiện cũ được lưu giữ |
| event_id | UUID | Danh tính sự kiện đã ký, không đổi khi thử lại và gửi lại thủ công |
| event_type | string | Một trong bảy sự kiện đăng ký |
| occurred_at | timestamp | Thời điểm sự kiện bất biến này được tạo, không phải thời điểm gửi đến |
| project_id | UUID | Phạm vi dự án của nhà bán hàng; đối chiếu với bên nhận đã cấu hình |
| store_id | UUID | Phạm vi cửa hàng của nhà bán hàng; đối chiếu với bên nhận đã cấu hình |
| description | string | null | Mô tả hóa đơn ban đầu |
| string | null | Email khách hàng tùy chọn tại thời điểm tạo sự kiện | |
| customer | object | Các trường metadata khách hàng tùy chọn được nhận diện; không suy đoán hay bổ sung dữ liệu cá nhân |
| metadata | object | Metadata gốc của nhà bán hàng như tại thời điểm tạo sự kiện |
| created_at | timestamp | Thời điểm tạo hóa đơn |
| updated_at | timestamp | Thời điểm cập nhật trạng thái hóa đơn |
| expires_at | timestamp | Hạn thanh toán hóa đơn |
| monitoring_expires_at | timestamp | Hạn theo dõi thanh toán muộn |
| settled_at | timestamp | null | Thời điểm quyết toán |
| paid_chain | string | null | 4.1.2+: slug chuỗi của phương thức quyết toán đã được chứng minh, ví dụ ethereum; null nếu chưa lưu quyết toán đủ điều kiện |
| paid_asset | string | null | 4.1.2+: mã đồng gốc hoặc token, ví dụ BTC, ETH hoặc USDC; là nhãn hiển thị, không phải danh tính tài sản duy nhất |
| paid_asset_amount | decimal string | null | 5.0.1+: toàn bộ số tiền đã khóa được yêu cầu theo đơn vị paid_asset, trước khi trừ dung sai; lưu khi quyết toán |
| paid_asset_amount_received | decimal string | null | 5.0.1+: tổng số tiền hợp lệ nhận được bằng phương thức được chọn để quyết toán tại lúc quyết toán, gồm phần thiếu/thừa được chấp nhận; được đóng băng, không phải số dư trực tiếp |
| paid_payment_method_id | UUID | null | 4.1.2+: ID ý định thanh toán dùng để quyết toán; khớp payment_info.methods[].payment_method_id và mạng/hợp đồng chính xác của nó |
| settlement_exchange_rate | object | null | 4.1.2+: bản chụp thị trường trước chênh lệch được lưu khi quyết toán, có đơn vị, loại tiền, dấu thời gian nguồn và cờ chất lượng rõ ràng; không bao giờ định giá lại lúc gửi |
| cancelled_at | timestamp | null | Thời điểm hủy |
| exchange_rate_spread_percent | decimal string | Mức chênh lệch đã khóa, không phải mặc định hiện tại của cửa hàng |
| underpayment_tolerance_percent | decimal string | Dung sai hóa đơn đã khóa; mỗi phương thức cũng báo dung sai có hiệu lực của nó |
| reason_code | string | null | Lý do chuyển trạng thái ở dạng máy đọc được |
| requires_review | boolean | Gợi ý ngoại lệ thanh toán; không phải quyền tự động hoàn tất đơn hàng hay hoàn tiền |
| links | object | URL trang thanh toán, hóa đơn có xác thực và các khoản thanh toán tại thời điểm tạo sự kiện. Áp dụng tùy chọn tên miền tại Cửa hàng → Cơ bản, rồi cửa hàng mặc định, rồi tên miền chính toàn cục; chỉ dùng tên miền đang hoạt động khớp vai trò. Lần thử lại giữ liên kết đã ký ban đầu; null nếu không có bản ghi máy chủ đang hoạt động. |
| payment_info | object | Phương thức thực tế đã quan sát, số tiền chính xác, báo giá đã khóa, bản chụp thị trường tham khảo và tập quan sát thanh toán có giới hạn; xem các nhóm trường bên dưới |
Tóm tắt quyết toán: settlement_exchange_rate
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
| rate / units / currency / symbol | strings | Số đơn vị tài sản trước chênh lệch cho một đơn vị tiền tệ hóa đơn. Chuỗi thập phân, không phải số tiền thanh toán hay giao dịch mua bán đã thực hiện. |
| observed_at / as_of | timestamps | Thời điểm ghi nhận quyết toán / dấu thời gian nguồn cũ hơn. Không coi dữ liệu lưu đệm là giá cập nhật trực tiếp. |
| pricing_provider / asset_provider / pricing_fetched_at / asset_fetched_at | strings / timestamps | Nguồn giá tiền pháp định và tài sản cùng thời điểm lấy dữ liệu, được lưu khi quyết toán. |
| stale / is_fixed / uses_reference_proxy / reference_currency | booleans / string | Cùng các cờ chất lượng như market_rate_at_event. Giá dự án cố định được gắn nhãn; tiền tham chiếu là USD. |
| Missing snapshot or price | null | Không suy đoán tỷ giá lịch sử. Trước quyết toán, mọi trường tóm tắt đều null; nếu chỉ thiếu giá, các mã định danh paid_* đã chứng minh vẫn có sẵn. |
Phương thức thanh toán: payment_info
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
| active_payment_method_id | UUID | null | Phương thức được chọn để quyết toán hoặc phương thức đã quan sát được chọn. Null trước khi phát hiện hoặc sau vô hiệu hóa; không suy đoán phương thức mặc định. |
| method_count / methods_truncated | integer / boolean | Tổng số phương thức đã quan sát và danh sách methods nhúng có chưa đầy đủ hay không. |
| methods[] | object[] | Tối đa tám phương thức đã quan sát, phương thức đang hoạt động ở đầu. Không cộng tổng giữa các tài sản. |
| payment_method_id / payment_rail | UUID / string | Danh tính ý định thanh toán hóa đơn và cách truyền onchain hoặc lightning. |
| chain_slug / network / caip_network_id | string | Danh tính mạng. Luôn ghép danh tính token với mạng của nó. |
| asset_id / asset_key / caip_asset_id | UUID / string / nullable string | Danh tính đã xác minh trong sổ đăng ký; chỉ ký hiệu không có tính duy nhất. |
| asset_name / symbol / asset_kind | string | Tên hiển thị tài sản, mã và loại đồng gốc hoặc token. |
| contract_address / token_standard | string | null | Hợp đồng hoặc mint và tiêu chuẩn token; null với tài sản gốc. |
| asset_decimals | integer | Độ chính xác đơn vị nhỏ nhất; Lightning BTC dùng 11. |
| destination_address / destination_tag | string | null | Địa chỉ nhận công khai và memo/tag bắt buộc. Địa chỉ là null với Lightning; không bao giờ là khóa riêng. |
| status | string | Trạng thái phương thức: pending, partial, paid, overpaid, expired hoặc invalid. Riêng paid không đồng nghĩa với quyết toán hóa đơn. |
| payment_count / payments_truncated / payments[] | integer / boolean / object[] | Tổng số quan sát và tối đa năm quan sát mới nhất. Mỗi quan sát được mô tả bên dưới. |
| links.payments | HTTPS URL | null | Lịch sử có phân trang và xác thực cho phương thức này trên origin API đã cấu hình. |
Số tiền chính xác: methods[].amounts
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
| expected_amount | decimal string | Báo giá đã khóa đầy đủ, sau chênh lệch và làm tròn lên. |
| received_amount / confirmed_amount | decimal strings | Tiền hợp lệ đã phát hiện / tiền đáp ứng chính sách xác nhận hoặc hoàn tất của phương thức này. |
| unconfirmed_amount | decimal string | max(received - confirmed, 0). Không phải số tiền cần gửi thêm. |
| minimum_payment_amount | decimal string | Ngưỡng được chấp nhận sau dung sai. Có thể thấp hơn báo giá đầy đủ. |
| remaining_amount | decimal string | max(minimum accepted - received, 0). Số tiền cần thêm để đạt ngưỡng được chấp nhận, không phải tiến độ xác nhận. |
| remaining_to_full_amount | decimal string | max(full quote - received, 0), không tính dung sai. |
| overpaid_amount | decimal string | max(received - full quote, 0). Không cho phép tự động hoàn tiền. |
| Every amount's *_atomic companion | integer string | Biểu diễn chính xác theo đơn vị nhỏ nhất. Dùng thư viện thập phân hoặc số nguyên; không dùng float hay JavaScript Number cho tiền. |
Chính sách xác nhận: methods[].acceptance
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
| finality_mode / required_confirmations | string / integer | Số xác nhận hoặc chính sách finalized đã khóa. Không xác nhận là lựa chọn được chính sách nhà bán hàng cho phép rõ ràng, không phải tính hoàn tất phổ quát của mạng. |
| observed_confirmations | integer | null | Mức tối thiểu trong các quan sát hợp lệ, không chỉ khoản chuyển mới nhất. Null với Lightning hoặc khi không có quan sát hợp lệ. |
| underpayment_tolerance_percent | decimal string | Dung sai có hiệu lực của phương thức. Lightning dùng mức không ngay cả khi hóa đơn có dung sai trên chuỗi khác không. |
Tỷ giá: methods[].quote và market_rate_at_event
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
| quote.effective_rate / units / currency / symbol | strings | Tỷ giá asset_per_invoice_currency đã khóa, gồm chênh lệch; currency và symbol nêu rõ chiều quy đổi. |
| quote.exchange_rate_spread_percent / quote_expires_at | decimal string / timestamp | Mức chênh lệch và hạn báo giá đã khóa. Không bao giờ thay bằng cài đặt cửa hàng hiện tại. |
| quote.reference_rate / unrounded_payment_amount / rounding_adjustment | decimal string | null | Giá tham chiếu trước chênh lệch, số tiền thanh toán trước làm tròn và phần điều chỉnh tăng theo đơn vị tài sản. |
| quote.pricing_provider / asset_provider / pricing_fetched_at / asset_fetched_at | string or timestamp | null | Nguồn/thời điểm định giá tiền tệ và tài sản ban đầu. Không có khóa API hay thông tin xác thực nhà cung cấp. |
| quote.provenance_available / rounding | boolean / string | False với hóa đơn cũ không lưu bản chụp nguồn; làm tròn theo chiều tăng. |
| market_rate_at_event | object | null | Bản chụp thị trường lưu đệm để tham khảo tại lúc tạo sự kiện. Dữ liệu thiếu giữ null; nó không bao giờ thay đổi số tiền hóa đơn hay trì hoãn để lấy dữ liệu qua mạng. |
| market_rate_at_event.rate / units / currency / symbol | strings | Tỷ giá thị trường trước chênh lệch, có cùng chiều quy đổi rõ ràng như quote. |
| market_rate_at_event.observed_at / as_of / pricing_fetched_at / asset_fetched_at | timestamps | Thời điểm chụp sự kiện / thời điểm cũ hơn trong hai nguồn / thời điểm từng nguồn. |
| market_rate_at_event.pricing_provider / asset_provider | strings | Nguồn tiền tệ và tài sản lưu đệm, gồm giá token tùy chỉnh đã cấu hình. |
| market_rate_at_event.stale / is_fixed / uses_reference_proxy / reference_currency | booleans / string | Bộ nhớ đệm có cũ không, giá token có cố định không hoặc tham chiếu USD có dùng stablecoin đại diện không. Tiền tham chiếu là USD. Cờ cũ chỉ để tham khảo, không bao giờ là báo giá mới. |
Bản ghi chuyển tiền: methods[].payments[] và GET …/payments
| Trường | Kiểu | Ý nghĩa |
|---|---|---|
| payment_id / payment_method_id | UUID | Danh tính quan sát / danh tính ý định thanh toán cha. Dùng payment_id để loại trùng lịch sử. |
| transaction_id / payment_hash / event_index | string | null / integer | Mã băm trên chuỗi và chỉ mục chuyển khoản/log/đầu ra, hoặc mã băm Lightning. Lightning không có giao dịch hay liên kết trình khám phá. |
| payment_rail / chain_slug / network / asset_id / asset_key / caip_asset_id / symbol / asset_decimals | strings / UUID / integer | Cùng mã định danh tài sản và mạng như phương thức chứa nó. |
| amount / amount_atomic | decimal / integer strings | Giá trị chính xác của khoản chuyển này, không bao giờ là quy đổi tiền pháp định. |
| status / counts_towards_received | string / boolean | detected, confirming và final được tính; reorged, replaced và invalid không được tính. Giữ lịch sử bị vô hiệu hóa để đối soát. |
| confirmations / block_height | integer | null | Dữ liệu khối của quan sát; confirmations là null với Lightning. |
| observed_at / chain_time / finalized_at | timestamp | null | Thời điểm thấy lần đầu tại máy cục bộ, thời gian chuỗi tin cậy nếu có và thời điểm đạt tính hoàn tất theo chính sách nếu đã đạt. |
| explorer_name / explorer_url | string | null | Tham chiếu trình khám phá khối công khai đã xác thực, nơi được hỗ trợ. |
Merchant 5.13.3 loại các khoản chuyển cấp gas nội bộ đã xác minh khỏi tổng thanh toán của khách hàng, payment_info, API thanh toán hóa đơn, giới hạn hoàn tiền và sự kiện payment.received. Bản ghi chuỗi/ngân quỹ của chúng vẫn có để kế toán ví. Chuyển khoản thông thường và khoản thừa thực sự vẫn được tính. Nội dung callback đã ký hiện có không bao giờ bị viết lại. Nếu quyết toán trước đây dựa vào cấp tiền nội bộ thay vì tiền khách hàng, đối soát phát invoice.invalid với reason_code internal_gas_funding_excluded; hãy xem xét thay vì hoàn tất đơn hàng lần nữa.
Merchant 4.1.0 thêm payload_version 2 mà không di chuyển hay thay đổi chín trường gốc. Sự kiện đã xếp hàng trước đó giữ nguyên nội dung và có thể không có payload_version. event_id, event_type và ID dự án/cửa hàng nay nằm trong nội dung đã ký; header sự kiện/lần gửi ở tầng truyền tải vẫn không được ký.
payment_info mô tả thanh toán đã quan sát, không phải mọi lựa chọn được cung cấp trên trang thanh toán. Trước phát hiện, active_payment_method_id là null và methods rỗng. Quan sát reorged/invalid có thể vẫn ở trong methods ngay cả khi phương thức đang hoạt động trở thành null. Không bao giờ cộng số tiền từ tài sản hoặc mạng khác nhau.
Mọi số tiền, số nguyên đơn vị nhỏ nhất, tỷ giá và tỷ lệ phần trăm đều là chuỗi. received_amount gồm tiền hợp lệ đang chờ xác nhận; confirmed_amount đáp ứng chính sách hoàn tất của phương thức đó. remaining_amount là max(minimum_payment_amount trừ received_amount, 0); remaining_to_full_amount là max(expected_amount trừ received_amount, 0). Ví dụ: dự kiến 100 USDC, nhận 99, dung sai 1% nghĩa là remaining_amount 0 và remaining_to_full_amount 1. Vẫn cần tính hoàn tất.
quote là phép tính hóa đơn đã khóa: số đơn vị tài sản cho một đơn vị tiền tệ hóa đơn. Chênh lệch được áp dụng trước khi làm tròn lên. Dùng expected_amount_atomic để so sánh thanh toán chính xác; riêng tỷ giá hiển thị có thể không tái tạo được việc làm tròn lên. Hóa đơn cũ không lưu nguồn gốc dữ liệu cung cấp các trường nguồn/tham chiếu/làm tròn null và provenance_available false, không bao giờ trình bày dữ liệu hôm nay như báo giá lịch sử.
market_rate_at_event là dữ liệu lưu đệm tham khảo trước chênh lệch, đóng băng khi tạo sự kiện. Nó có thời gian nguồn, cờ dữ liệu cũ và cờ tham chiếu đại diện; là null nếu không có cặp lưu đệm dùng được. Không có yêu cầu tỷ giá trực tiếp nào chặn thông báo, và quan sát thị trường này không bao giờ thay đổi số tiền phải trả. Token tùy chỉnh giá cố định được gắn is_fixed; token DEX dùng nguồn riêng của dự án, không dùng token cùng ký hiệu.
Các trường cấp cao nhất paid_chain, paid_asset, paid_payment_method_id và settlement_exchange_rate (4.1.2+) xác định phương thức đã được chứng minh dùng để quyết toán sau quyết toán, không phải lựa chọn trên trang thanh toán hay tổng các phương thức khác nhau. Trước quyết toán, sau vô hiệu hóa, với quyết toán cũ không có bản chụp, hoặc chấp nhận thủ công mà không có tiền đạt mức hoàn tất theo chính sách, các trường tóm tắt là null. Ký hiệu chỉ là nhãn hiển thị: theo ID phương thức để lấy danh tính mạng/tài sản/hợp đồng chính xác.
Merchant 5.0.1 thêm paid_asset_amount và paid_asset_amount_received dưới dạng chuỗi thập phân chính xác theo đơn vị paid_asset; payload_version vẫn là 2. paid_asset_amount là báo giá đã khóa đầy đủ, gồm chênh lệch và làm tròn lên, không bao giờ là ngưỡng dung sai hay số dư còn lại. paid_asset_amount_received là tổng khoản nhận hợp lệ của phương thức quyết toán tại lúc quyết toán, gồm tiền đang chờ xác nhận và phần thiếu hoặc thừa được chấp nhận. Ví dụ: báo giá 100 USDC, nhận 99 và chấp nhận theo dung sai sẽ cho 100 và 99, không phải 99 và 99. Cả hai được đóng băng cùng bản chụp quyết toán; dùng payment_info.methods[].amounts để xem khoản nhận tại mỗi sự kiện hoặc API thanh toán để xem bản ghi hiện tại. Chúng là null nếu không có bản chụp đủ điều kiện và với bản chụp trước 5.0.1; nội dung sự kiện cũ đang xếp hàng không đổi. Không bao giờ đổi chuỗi thập phân chính xác sang số dấu phẩy động để kế toán.
settlement_exchange_rate là quan sát thị trường lưu đệm trước chênh lệch được ghi nhận cùng quyết toán, không phải báo giá hóa đơn đã khóa hay giao dịch đổi tiền đã thực hiện. Cấu trúc khớp market_rate_at_event; 1.17 asset_per_invoice_currency với EUR/USDC nghĩa là 1 EUR = 1.17 USDC. Dấu thời gian nguồn và cờ cũ/cố định/đại diện mô tả chất lượng của nó. Thiếu cặp giá khiến tỷ giá là null nhưng phương thức đã chứng minh vẫn có các trường paid_*. Nó không bao giờ thay đổi số tiền phải trả hay chờ gọi trực tiếp nhà cung cấp. Thanh toán sau bằng cùng phương thức, thử lại và gửi lại không thể thay bản chụp đã lưu, kể cả tỷ giá null đã lưu. Quyết toán lại thực sự hoặc đổi phương thức quyết toán sẽ ghi bản chụp mới; observed_at xác định lần ghi đó, còn settled_at có thể giữ thời điểm quyết toán đầu tiên. Nội dung sự kiện cũ giữ nguyên.
Bao gồm tối đa tám phương thức đã quan sát và năm quan sát thanh toán mới nhất mỗi phương thức, kèm số lượng và cờ cắt bớt. Hạn mức payload có thể thu nhỏ các mảng này hơn nữa. Một quan sát thanh toán là một khoản chuyển/log/đầu ra UTXO, không nhất thiết là một mã băm giao dịch duy nhất. Dùng GET /v1/projects/YOUR_PROJECT_ID/invoices/{invoice_id}/payments với payment_method_id, limit và offset để lấy toàn bộ lịch sử hiện tại. Chi tiết hóa đơn giữ mọi phương thức đã báo giá và quote_details của nó. Liên kết API cần máy chủ và thông tin xác thực đã cấu hình của bạn; không bao giờ chuyển token bearer đến URL tùy ý do callback cung cấp.
Lightning dùng payment_hash thay transaction_id; địa chỉ nhận, trình khám phá và số xác nhận quan sát đều null. Số BTC chính xác dùng 11 chữ số thập phân (millisatoshi), và dung sai hiệu lực bằng không. Không bao gồm preimage thanh toán BOLT11, khóa ví, bí mật ký hay thông tin xác thực nhà cung cấp. Trường khách hàng/metadata chỉ thuộc phản hồi nhà bán hàng và callback đã ký, không bao giờ thuộc trang thanh toán công khai; đừng đưa thông tin xác thực vào metadata.
Nhận an toàn
- Xác minh nội dung thô chính xác bằng bí mật tương ứng trước khi phân tích. Cửa hàng → IPN cung cấp bí mật IPN, gồm cả lần gửi đến ipn_url tùy chỉnh. Mỗi endpoint Cửa hàng → Webhook có bí mật riêng. Cả hai đều không phải token API; luân chuyển một bí mật không luân chuyển các bí mật khác.
- Kiểm tra dấu thời gian đã ký (mặc định SDK: năm phút về mỗi phía) và đối chiếu ID dự án/cửa hàng đã ký với cấu hình bên nhận khi có. Đưa vào hàng đợi bền vững trước khi trả HTTP 2xx. Với xử lý từng sự kiện, event_id v2 được ký; chỉ ID trong header không chống phát lại vì header không được ký. Với hộp nhận trạng thái đơn hàng, loại trùng invoice_id và sequence rồi so sánh các trường trạng thái hóa đơn gốc, không phải toàn bộ nội dung v2: các loại/ID sự kiện khác nhau có thể cùng phiên bản sửa đổi.
- Trong tiến trình nền, lấy hóa đơn hiện tại từ origin API đã cấu hình, không từ liên kết callback tùy ý. Đối chiếu đơn hàng đã lưu, dự án/cửa hàng, số tiền và loại tiền, yêu cầu trạng thái hiện tại là settled, rồi áp dụng chính sách chấp nhận thủ công và ngoại lệ. Khóa đơn hàng và hoàn tất một lần trong giao dịch cơ sở dữ liệu, độc lập với loại trùng sự kiện.
- Không bao giờ áp dụng sequence cũ đè lên mới. Các sự kiện khác nhau có thể cùng phiên bản sửa đổi; đừng kết hợp loại trùng cấp phiên bản với bộ lọc chỉ invoice.settled. Mở lại/đối soát có thể thay đổi trạng thái; sequence, không phải thứ hạng trạng thái cố định, quyết định thứ tự cập nhật. Ghi lại đảo ngược để xem xét thay vì hoàn tất đơn hàng lần nữa.
Ví dụ bên nhận: PHP · Python · Node.js / TypeScript.
Xác minh chữ ký & quy tắc gửi
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyWhollySignature(rawBody, header, signingSecret, toleranceSeconds = 300) {
const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header || "");
if (!match) return false;
const timestamp = Number(match[1]);
if (!Number.isSafeInteger(timestamp)) return false;
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - timestamp) > toleranceSeconds) return false;
// rawBody must be the exact request Buffer, before JSON parsing.
const expected = createHmac("sha256", signingSecret)
.update(String(timestamp))
.update(".")
.update(rawBody)
.digest();
const presented = Buffer.from(match[2], "hex");
return timingSafeEqual(expected, presented);
}| Quy tắc gửi | Chi tiết |
|---|---|
| Header | Wholly-Signature, Wholly-Event-Id và Wholly-Delivery-Id; Content-Type là application/json. |
| Chữ ký | HMAC-SHA256 trên <unix timestamp>.<exact raw body>; định dạng header t=<timestamp>,v1=<64 lowercase hex>. |
| Thành công | Bất kỳ phản hồi HTTP 2xx nào. Không theo chuyển hướng; phản hồi ngoài 2xx là thất bại. |
| Thời gian chờ | Thời gian chờ kết nối 5 giây và thời gian chờ toàn yêu cầu 10 giây. |
| Lịch thử lại | Tối đa 8 lần cho lỗi có thể thử lại: ngay lập tức, rồi chờ 10 giây, 1 phút, 5 phút, 15 phút, 1 giờ, 6 giờ và 24 giờ sau khi lần trước kết thúc. IPN tự động thử lại; có thể tắt thử lại tự động của webhook theo từng endpoint. |
| An toàn đích đến | Chỉ HTTPS công khai. DNS được xác thực lại và ghim khi gửi; đích cục bộ/riêng/dành riêng bị từ chối. |
| Lưu giữ sự kiện | Payload sự kiện thông báo và lịch sử gửi được lên lịch lưu 90 ngày; chi tiết lưu giữ được dọn theo lô có giới hạn. |
| Loại trùng | Lưu bền vững invoice_id và sequence đã ký trong phạm vi dự án đã cấu hình. Wholly-Event-Id định danh sự kiện; Wholly-Delivery-Id định danh bản ghi gửi (lần thử lại dùng lại nó; gửi lại thủ công tạo bản ghi khác). Cả hai header ID đều không được ký. |
| Đặt tên sự kiện | Phiên bản 2 ký event_id và event_type trong nội dung. Sự kiện cũ đang xếp hàng không có cả hai. Các loại sự kiện khác nhau có thể cùng sequence hóa đơn; đối soát trạng thái hóa đơn theo phiên bản sửa đổi hoặc loại trùng từng sự kiện theo event_id đã ký. |
| Luân chuyển bí mật | Luân chuyển không có thời gian chồng lấp hay header phiên bản, và lập tức đổi chữ ký cho lần gửi đang xếp hàng, thử lại và thủ công. |
| Lần gửi tạm dừng | Thiếu tín dụng xử lý sẽ tạm dừng IPN/webhook, kể cả thử lại. Vẫn tiếp tục nhận thanh toán; thông báo xếp hàng tiếp tục sau khi nạp tiền trong thời hạn lưu payload. |
Trợ lý AI · MCP
Kết nối trợ lý với bản cài đặt nhà bán hàng của bạn.
Merchant 5.0.0 có máy chủ MCP tùy chọn bật trên tên miền API đã cấu hình. Nó chạy trong bản cài đặt của bạn, không qua relay Wholly Crypto dùng chung.
- Mở Cài đặt → Truy cập API. Tạo thông tin xác thực riêng, chỉ gán các dự án trợ lý cần và bắt đầu với quyền chỉ đọc. Với tài khoản do nhà vận hành lưu trữ, nhà vận hành bật dịch vụ MCP của bản cài đặt trước; bạn chỉ quản lý thông tin xác thực và quyền cấp của mình.
- Trong Kết nối AI · MCP, bật MCP, chọn thông tin xác thực và lưu quyền MCP của nó. Thông tin xác thực hiện có không có quyền MCP cho đến khi được bật rõ ràng.
- Sao chép URL máy chủ MCP vào cài đặt máy chủ HTTP từ xa của ứng dụng khách. Với OAuth, đăng nhập bảng điều khiển nhà bán hàng, xem tên ứng dụng khách và địa chỉ trả về, chọn thông tin xác thực rồi phê duyệt. Basic Auth và TOTP hiện có vẫn bảo vệ bạn.
- Tạo hóa đơn còn cần thông tin xác thực đọc/ghi, Đọc + tạo hóa đơn trong chính sách MCP, phạm vi OAuth mcp:invoice:create và phê duyệt rõ ràng. Kết nối OAuth không bao giờ được thêm quyền với dự án được bổ sung vào thông tin xác thực sau khi phê duyệt.
{
"mcpServers": {
"whollycrypto": {
"url": "https://api.example.com/mcp"
}
}
}| Công cụ | Truy cập | Mục đích |
|---|---|---|
| list_projects | Đọc | Các dự án đang bật được gán cho kết nối; phân trang limit/offset. |
| list_stores | Đọc | Cửa hàng, ID và trạng thái bật trong project_id; phân trang limit/offset. |
| list_payment_methods | Đọc | Phương thức chuỗi, token và Lightning đã cấu hình cho project_id + store_id. |
| get_wallet_balances | Đọc | Địa chỉ nhận và số dư lưu đệm, kèm các trường độ mới/khả dụng; không bao giờ có bí mật ví. |
| list_invoices | Đọc | Hóa đơn dự án, lọc theo cửa hàng, trạng thái hoặc tìm kiếm; phân trang limit/offset. |
| get_invoice | Đọc | Chi tiết hóa đơn đầy đủ và liên kết thanh toán dùng project_id + invoice_id. |
| get_delivery_history | Đọc | Trạng thái IPN/webhook cửa hàng, số lần thử và kết quả HTTP. Bộ lọc invoice_id/kind tùy chọn; không có bí mật hay nội dung callback. |
| convert_amount | Đọc | Quy đổi tham khảo lưu đệm dùng from, to và amount dạng chuỗi thập phân; không phải báo giá hóa đơn. |
| create_invoice | Quyền ghi rõ ràng | project_id, store_id, idempotency_key và invoice (nội dung tạo hóa đơn hiện có). invoice.payment_methods lọc phương thức đang bật của cửa hàng; 5.4.0+ bỏ qua lựa chọn không hoạt động/không được chấp nhận và dùng mặc định cửa hàng nếu không có lựa chọn khớp. Chỉ chọn chuỗi sẽ chọn mọi tài sản đang hoạt động được chấp nhận. asset_tickers theo phạm vi chuỗi được hỗ trợ từ 5.3.0. Trả về phản hồi hóa đơn thông thường. |
Giao thức, OAuth & an toàn
Dùng Streamable HTTP qua HTTPS. Thương lượng một phiên bản giao thức được công bố và thêm MCP-Protocol-Version vào các POST tiếp theo. Gửi Content-Type: application/json và Accept: application/json, text/event-stream. Phản hồi là JSON hữu hạn; kết nối lại không cần ID phiên MCP.
OAuth dùng token truy cập ngắn hạn (15 phút), mã S256 PKCE dùng một lần (5 phút) và token làm mới luân chuyển (thời hạn kết nối 30 ngày). Dùng lại token làm mới đã dùng sẽ thu hồi kết nối đó. Kết nối lại sau khi hết hạn, luân chuyển thông tin xác thực, thay đổi chính sách hoặc đổi tên miền API chính thức.
Khám phá OAuth chỉ công khai khi MCP được bật. Tham số resource phải bằng URL chính thức do khám phá trả về, gồm /mcp. Hỗ trợ đăng ký động; không hỗ trợ tài liệu metadata client-ID từ xa và bí mật ứng dụng khách.
Với ứng dụng khách hỗ trợ header Authorization tùy chỉnh, có thể dùng token API nhà bán hàng đã bật MCP làm Bearer. Nó giữ quyền REST riêng; nên dùng OAuth cho kết nối chỉ giới hạn ở MCP. Không bao giờ dán thông tin xác thực vào cuộc trò chuyện, URL, đối số công cụ hay hệ thống quản lý mã nguồn.
MCP dùng chung hạn mức REST mỗi phút và giới hạn IP nguồn chính xác của thông tin xác thực, cộng với giới hạn IP máy chủ API. OAuth không vượt qua danh sách cho phép. Với ứng dụng khách AI từ xa, cho phép IP đầu ra được công bố của họ hoặc chủ động để giới hạn này tắt. Không áp dụng thử thách bảo mật web hay bộ nhớ đệm cho tuyến MCP/OAuth.
Lỗi HTTP: 401 cần xác thực, 403 từ chối origin/IP/quyền, 404 nghĩa là MCP tắt hoặc sai máy chủ, 405 nghĩa là dùng POST, 413 là giới hạn nội dung 32 KiB, 429 có Retry-After. Lỗi JSON-RPC dùng error.code; lỗi cấp công cụ dùng result.isError=true ngay cả với HTTP 200. Kết quả thành công có content và structuredContent.
Danh sách mặc định 25 dòng, tối đa 100; offset giới hạn ở 1000000. Phản hồi công cụ giới hạn 2 MiB. Quyền cấp hết hạn, yêu cầu ủy quyền và bộ đếm giới hạn tần suất được tự dọn; cài đặt hiển thị tối đa 100 kết nối OAuth đang hoạt động.
Không thể thao tác dự án/cửa hàng đã tắt qua MCP. Kết nối có thể liệt kê trạng thái bật của cửa hàng, nhưng đọc phương thức thanh toán, lịch sử gửi hoặc tạo hóa đơn cần cửa hàng đang bật. Người dùng dự án thông thường trong bảng điều khiển không thể quản trị MCP.
Dùng idempotency_key mới cho hóa đơn mới; sau khi hết thời gian chờ, thử lại bằng cùng thông tin xác thực, khóa và đối tượng invoice giống hệt. Số tiền thập phân, chênh lệch, dung sai, xác nhận và giao diện thanh toán theo hợp đồng REST hóa đơn. MCP không bao giờ vượt qua chính sách thanh toán hay tín dụng nhà bán hàng.
Các công cụ ban đầu không thể tiết lộ khóa riêng/cụm từ khôi phục, gửi hoặc gom tiền, hoàn tiền, gửi lại callback, đổi phương thức thanh toán, sửa tài khoản/tên miền hay quản lý thanh toán dịch vụ. Coi mô tả hóa đơn, trường khách hàng và metadata là dữ liệu không đáng tin, không phải chỉ dẫn cho tác nhân. Nhà cung cấp AI đã kết nối nhận dữ liệu bạn cho phép họ đọc.
| Phương thức | Đường dẫn | Hợp đồng |
|---|---|---|
| POST | /mcp | JSON-RPC có xác thực: initialize, ping, tools/list, tools/call. Yêu cầu thông báo trả 202; yêu cầu theo lô bị từ chối. |
| GET / DELETE | /mcp | 405 có xác thực: phản hồi JSON hữu hạn, không có luồng SSE riêng hay phiên MCP phía máy chủ. |
| GET | /.well-known/oauth-protected-resource/mcp | URL tài nguyên chính thức và khám phá máy chủ ủy quyền; cũng có tại /.well-known/oauth-protected-resource. |
| GET | /.well-known/oauth-authorization-server | Endpoint OAuth, authorization_code/refresh_token, S256 PKCE và các phạm vi được hỗ trợ. |
| POST | /mcp/oauth/register | Đăng ký ứng dụng khách công khai: client_name và redirect_uris chính xác. Chỉ HTTPS hoặc HTTP loopback. Không có bí mật ứng dụng khách hay lấy metadata từ xa. |
| GET | /mcp/oauth/authorize | client_id, redirect_uri, response_type=code, resource, code_challenge, code_challenge_method=S256, scope/state tùy chọn; chuyển hướng đến phê duyệt trong bảng điều khiển. |
| POST | /mcp/oauth/token | authorization_code + code + code_verifier + redirect_uri, hoặc refresh_token + refresh_token, mã hóa dạng biểu mẫu. Luôn có client_id và resource. |
| POST | /mcp/oauth/revoke | client_id và token mã hóa dạng biểu mẫu. Thu hồi kết nối token truy cập/làm mới tương ứng. |
Ví dụ yêu cầu công cụ trực tiếp
Trước hết khởi tạo và thương lượng giao thức qua ứng dụng khách MCP. Ví dụ này cho thấy yêu cầu tiếp theo.
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/mcp" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'MCP-Protocol-Version: 2025-11-25' \
--header 'Accept: application/json, text/event-stream' \
--header 'Content-Type: application/json' \
--data-raw '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_invoices",
"arguments": {
"project_id": "YOUR_PROJECT_ID",
"limit": 10
}
}
}'// 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");
const body = `{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_invoices",
"arguments": {
"project_id": "YOUR_PROJECT_ID",
"limit": 10
}
}
}`;
const response = await fetch("https://api.example.com/mcp", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"MCP-Protocol-Version": "2025-11-25",
"Accept": "application/json, text/event-stream",
"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'); }
$body = <<<'JSON'
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_invoices",
"arguments": {
"project_id": "YOUR_PROJECT_ID",
"limit": 10
}
}
}
JSON;
$ch = curl_init("https://api.example.com/mcp");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "MCP-Protocol-Version: 2025-11-25", "Accept: application/json, text/event-stream", "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
headers = {
"MCP-Protocol-Version": "2025-11-25",
"Accept": "application/json, text/event-stream",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_invoices",
"arguments": {
"project_id": "YOUR_PROJECT_ID",
"limit": 10
}
}
}""".encode("utf-8")
request = Request("https://api.example.com/mcp",
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))API Operator
Cấp phát nhà bán hàng được lưu trữ bằng khóa phía máy chủ riêng có giới hạn phạm vi.
Lưu trữ nhiều doanh nghiệp và tự động hóa thiết lập qua api.example.com/v1/operator. Có từ 7.4.0, chỉ trong chế độ Operator. Merchant API thông thường không đổi.
- Mở Operator → Cài đặt → Operator API và bật (mặc định tắt). Tạo thông tin xác thực riêng chỉ với quyền và nhà bán hàng được lưu trữ cần thiết.
- Giữ khóa wc_operator_ trên máy chủ của bạn. Dùng tên máy chủ API, không dùng tên máy chủ bảng Operator hay khóa nhà bán hàng.
- Lưu bền vững Idempotency-Key và nội dung yêu cầu chính xác trước mỗi Operator POST. Đọc lại tài khoản sau kết quả không chắc chắn; không bao giờ thay khóa chỉ để thử lại.
- Tạo nhà bán hàng với onboarding: direct và mật khẩu, hoặc onboarding: invitation và không có mật khẩu. Sau đó tạo dự án/cửa hàng và cấp khóa nhà bán hàng giới hạn theo dự án cho tích hợp thanh toán.
| Phạm vi | Truy cập |
|---|---|
| merchants.read / merchants.write | Liệt kê/đọc và tạo/cập nhật nhà bán hàng được lưu trữ. |
| users.read / users.write / users.security | Đọc/tạo/cập nhật người dùng; đổi mật khẩu hoặc thu hồi phiên riêng biệt. Không bao giờ tạo quản trị viên nhà vận hành. |
| invitations.read / invitations.write | Liệt kê/đọc, tạo, thay và thu hồi liên kết mời/đặt lại dùng một lần. Người dùng mới còn cần users.write; đặt lại còn cần users.security. |
| credits.read / credits.write / fees.write | Đọc số dư/sổ cái; cấp hoặc điều chỉnh tín dụng cục bộ; đặt phí cho tương lai. Tín dụng khởi đầu khác không cần credits.write. |
| topups.read / topups.write | Đọc hoặc tạo yêu cầu thanh toán nạp tín dụng cho nhà bán hàng được lưu trữ. Không thao tác API nào có thể đánh dấu yêu cầu là đã thanh toán. |
| projects.read / projects.write / reports.read | Cấp phát dự án, cửa hàng, giao diện và cài đặt thanh toán của nhà bán hàng; đọc hóa đơn, số dư ví và báo cáo tài chính. |
| merchant_credentials.read / merchant_credentials.write | Quản lý khóa nhà bán hàng thông thường có giới hạn phạm vi. Quyền mạnh: các khóa đó hoạt động độc lập sau khi cấp. |
| events.read / webhooks.write / audit.read / health.read | Đọc lịch sử vòng đời; cấu hình callback vòng đời đã ký; đọc kiểm toán/khả năng/tình trạng nút. |
Tiếp nhận, tín dụng, quyền và thử lại an toàn
| Chủ đề | Quy tắc |
|---|---|
| Thông tin xác thực | Thời hạn tùy chọn và danh sách cho phép IPv4/IPv6 chính xác; mặc định 60 yêu cầu/phút, cấu hình được 1–600. Mỗi yêu cầu kiểm tra quản trị viên cấp khóa và phạm vi hiện tại. HTTP 429 có Retry-After. |
| Cô lập | Khóa chỉ truy cập nhà bán hàng được lưu trữ đã gán. Tạo nhà bán hàng và xem báo cáo toàn bản cài đặt cần quyền truy cập mọi nhà bán hàng. Doanh nghiệp riêng của nhà vận hành không nằm trong phạm vi này. |
| Đăng nhập lần đầu | Tài khoản trực tiếp thừa nhận bên lưu trữ có thể truy cập khóa ví. require_password_change thêm bước đổi mật khẩu khi đăng nhập lần đầu. Chấp nhận lời mời cần xác nhận rõ mô hình lưu ký, rồi đăng nhập bình thường. Basic Auth và TOTP hiện có vẫn áp dụng. |
| Lời mời | Liên kết người dùng mới có hiệu lực 48 giờ; liên kết đặt lại mật khẩu có hiệu lực một giờ. Token dùng một lần. Cấp lại sẽ thu hồi liên kết cũ. SMTP chấp nhận không bảo đảm thư đến hộp thư; kiểm tra email_delivery. |
| Thử lại an toàn | Mỗi Operator POST cần khóa dài 16–128 ký tự (chữ, số, -, _ hoặc .). Cùng khóa và URL/nội dung chính xác trả kết quả đã lưu. Khác byte trả 409. Bí mật/liên kết bị lược khi phát lại; khi cần, luân chuyển hoặc cấp lại qua một thao tác mới rõ ràng. |
| Kết quả không chắc chắn | operator_request_in_progress nghĩa là thao tác đang chạy hoặc đã bị gián đoạn trước khi ghi biên nhận. Kiểm tra tài nguyên và nhật ký kiểm toán; đừng mù quáng gửi khóa mới. Biên nhận hoàn tất được rút gọn sau 30 ngày; khóa cũ vẫn không thể chạy lại. |
| Tín dụng và phí | Chuỗi thập phân, tối đa sáu chữ số thập phân. starting_credit là khoản cấp cục bộ một lần. Điều chỉnh cần số tiền có dấu, ghi chú và request_id, cùng khóa thử lại HTTP. fee_bps=100 nghĩa là 1%; thay đổi áp dụng cho hóa đơn tương lai. Khoản cấp không nạp số dư trả trước riêng của bản cài đặt. |
| Tạm dừng | enabled=false tắt tài khoản được lưu trữ và thu hồi phiên bảng điều khiển. payments_paused=true dừng hóa đơn mới. Theo dõi thanh toán hiện có vẫn tiếp tục. Việc tạo dự án/cửa hàng và tự động hóa vẫn theo chính sách tín dụng của bản cài đặt. |
| Không cung cấp | Không có bí mật ví, ký, gửi tiền, hoàn tiền, xóa vĩnh viễn, đặt lại TOTP, đổi tên miền hay cấu hình cấp máy chủ. Yêu cầu hóa đơn thông thường vẫn dùng khóa nhà bán hàng và Merchant API. |
Webhook vòng đời Operator
| Sự kiện | Dữ liệu |
|---|---|
| merchant.created / merchant.updated | merchant_id, enabled, payments_paused, fee_bps. |
| user.created / user.updated | merchant_id, user_id, enabled. Sự kiện cập nhật bao gồm thay đổi email, trạng thái bật và vai trò quản trị viên. |
| invitation.accepted / password_reset.completed | merchant_id, user_id, invitation_id. |
| topup.settled / credit.balance_changed | merchant_id, ledger_id, kind, amount và balance. Đọc loại tiền tín dụng nhà bán hàng hoặc chi tiết sổ cái khi đối soát. |
Sự kiện vòng đời Operator tách biệt với IPN hóa đơn/webhook cửa hàng. Đăng ký thuộc thông tin xác thực Operator đã tạo nó, tối đa 10 endpoint mỗi khóa. Chỉ sự kiện tương lai khớp điều kiện được xếp hàng; dùng GET /events để xem lịch sử được lưu giữ.
Nội dung gồm event_id, event_type, merchant_id, occurred_at và data. Xác minh Wholly-Signature trên nội dung thô chính xác bằng signing_secret chỉ hiển thị một lần của endpoint: HMAC-SHA256(secret, timestamp + '.' + raw_body), header t=...,v1=.... Áp dụng dung sai dấu thời gian ngắn.
Dùng trình xác minh chữ ký tổng quát của SDK, không dùng trình phân tích thông báo hóa đơn. Sau đó xác thực merchant_id và event_type, lưu/loại trùng event_id trong giao dịch và chỉ trả 2xx sau khi tiếp nhận bền vững. Wholly-Event-Id phải khớp nội dung đã ký. Không coi header chưa ký là dữ liệu nghiệp vụ.
Sự kiện được gửi ít nhất một lần, có thể đến sai thứ tự và được thử tối đa 8 lần. Đọc tài nguyên hiện tại để đối soát; occurred_at không phải trình tự tăng đơn điệu. Phạm vi và cài đặt bật/hết hạn được kiểm tra lại trước khi gửi. Đăng ký bị tắt tạm dừng công việc đã xếp hàng nhưng không xếp sự kiện mới khi đang tắt.
Sự kiện và lịch sử gửi được lưu 30 ngày. Chính sách tự động hóa của bản cài đặt có thể tạm dừng gửi. GET /webhooks/{id}/deliveries hiển thị kết quả và payload bất biến; API công khai không ép gửi bản ghi đã hết hạn.
{
"event_id": "55555555-5555-4555-8555-555555555555",
"event_type": "merchant.created",
"merchant_id": "11111111-1111-4111-8111-111111111111",
"occurred_at": "2026-10-01T12:00:00Z",
"data": {
"merchant_id": "11111111-1111-4111-8111-111111111111",
"enabled": true,
"payments_paused": false,
"fee_bps": 300
}
}API sàn thương mại
Một trang thanh toán với phần tiền nhà bán hàng được bảo vệ và chi trả có kiểm soát.
Một hóa đơn khách hàng, phần chia chính xác cho nhà bán hàng và chi trả có kiểm soát bằng cùng tài sản. Bật tùy chọn theo dự án. Phiên bản 8.0.0 hỗ trợ Bitcoin mainnet và đồng gốc EVM / token ERC-20 tiêu chuẩn được hỗ trợ đã cấu hình, không phải mọi mạng nhận tiền.
- Bật Marketplace trong dự án, chọn cửa hàng tham gia và giữ chi trả tạm dừng trong lúc cấu hình.
- Đăng ký nhà bán hàng và xác minh độc lập địa chỉ chi trả. Đích nhận mới tạo ở trạng thái chờ; phê duyệt cần destinations.approve.
- Tạo thông tin xác thực Marketplace riêng trong Cài đặt → Truy cập API. Thông tin xác thực Merchant, Operator và MCP thông thường không thể chi tiêu tiền Marketplace.
- Tạo hóa đơn có 1–100 khoản phân bổ dương dạng chuỗi thập phân với tổng bằng chính xác số tiền hóa đơn. Mỗi nhà bán hàng cần đích nhận đã phê duyệt trên một mạng được hỗ trợ chung của cửa hàng.
- Chờ xác minh khoản phân bổ sẵn sàng. Chuẩn bị chi trả, đọc người nhận bất biến và giới hạn chi phí, rồi phê duyệt phiên bản sửa đổi và plan_hash chính xác. Thăm dò chi trả hoặc xác minh sự kiện đã ký.
| Chủ đề | Quy tắc |
|---|---|
| Lưu ký | Tiền khách hàng vào ví do dự án kiểm soát trước. Chủ sàn thương mại/máy chủ kiểm soát khóa đó đến khi nhà bán hàng được trả tiền. Đây không phải thanh toán trực tiếp từ khách hàng tới nhà bán hàng, dịch vụ ký quỹ hay hệ thống đăng nhập cho nhà bán hàng. |
| Ba nhà bán hàng | Hóa đơn 300 USD với ba phần 100 USD và hoa hồng 4% phân bổ lượng tiền mã hóa đã báo giá tương đương 96 USD cho mỗi nhà bán hàng, giữ lại hoa hồng gộp tương đương 12 USD. Kế hoạch bảo đảm đơn vị tiền mã hóa nhỏ nhất, không phải giá trị tiền pháp định tương lai. |
| Phí | Phí xử lý hiện có áp dụng một lần trên số tiền/loại tiền hóa đơn gốc đã quyết toán. Với mức cấu hình 1%, phí là 3 USD tín dụng trả trước, còn hoa hồng tương đương 9 USD trước phí chuỗi. Chi trả cho nhà bán hàng không tạo thêm phí bán hàng cho khách. |
| Phân bổ | Phân bổ theo phần dư lớn nhất giữ nguyên mọi đơn vị nhỏ nhất. Hoa hồng làm tròn xuống; phần ròng nhà bán hàng là phần còn lại. Ghi đè khoản phân bổ, ghi đè hóa đơn, ghi đè nhà bán hàng và mặc định cửa hàng/dự án được chụp lưu. Không áp dụng tỷ giá mới khi chi trả. |
| Tiền được bảo vệ | Gửi tiền, gom tiền, nạp sàn và tự nạp tín dụng thông thường loại trừ địa chỉ nhận Marketplace. Phí mạng và gas token cần đồng gốc tự do riêng. Giá trị ví lưu đệm chỉ để tham khảo; tiền bảo chứng được kiểm tra độc lập trực tiếp trước khi ký. |
| Tính hoàn tất | Bằng chứng chi trả Marketplace cần ngưỡng xác nhận chuỗi tối thiểu dương và hai nhà cung cấp tương thích độc lập, ngay cả khi trang thanh toán chấp nhận không xác nhận hay một máy quét. Thời gian chờ của nhà cung cấp trì hoãn xác minh thanh toán/chi trả, không trì hoãn tạo hóa đơn vốn hợp lệ. |
| Ngoại lệ | Khoản thiếu được dung sai thanh toán thông thường chấp nhận sẽ được giữ, không phân bổ quá mức. Thao tác giải phóng có đặc quyền có thể phê duyệt phần chia nhỏ hơn chính xác được bảo chứng đầy đủ. Chỉ riêng thanh toán thừa không bao giờ chặn phần chia đã báo giá của nhà bán hàng trên BTC hoặc phương thức đồng gốc EVM/ERC-20 được hỗ trợ. Phần thừa được giữ riêng. Bitcoin trả tiền thừa được bảo vệ về địa chỉ hóa đơn; tiền dự án riêng chi trả phí và phần bổ sung để đạt ngưỡng dust nếu có. Thanh toán trộn phương thức, muộn/mơ hồ/bị tái tổ chức và thiếu bảo chứng cần xem xét. |
| Hoàn tiền | Chuẩn bị hoàn toàn bộ tiền bằng cùng tài sản của một phương thức nhận đã xác nhận, không mơ hồ, rồi phê duyệt riêng như một khoản chi trả. Khoản phân bổ chưa trả và hoa hồng được đảo ngược. Khi mọi nhà bán hàng đã nhận tiền, nạp riêng vào địa chỉ ví chính; không có thu hồi bắt buộc. Lô nhà bán hàng mới trả một phần và hoàn tiền nhiều tài sản cần đối soát trước. Hoàn một phần số tiền và rút hoa hồng chưa được cung cấp trong 8.0.0. |
| Thử lại | Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn. |
| Phiên bản sửa đổi | Bản ghi có thể thay đổi cần phiên bản sửa đổi hiện tại. Phê duyệt/tiếp tục còn cần expected_plan_hash và confirm:true. Chuẩn bị giữ chỗ tiền trong 15 phút; phê duyệt cho phép một giờ. Công việc hết hạn chưa ký được giải phóng an toàn. Chuyển tiền đã ký/chưa chắc chắn giữ danh tính và phần tiền đã giữ chỗ. |
| Chi trả tự động | Mặc định tắt. Chính sách theo tài sản ủy quyền đích nhận đã phê duyệt, mức tối thiểu dương, giới hạn tiền gốc mỗi lần chi trả/trong 24 giờ trượt và giới hạn phí đồng gốc/gas, khoảng thời gian và xác nhận. Đổi/thu hồi quyền dừng công việc chưa gửi; việc quan sát tiếp tục. Giới hạn tính cả kế hoạch giữ chỗ và chưa chắc chắn. Chính sách bị tạm dừng do thanh toán dịch vụ được lên lịch lại công bằng. Hóa đơn không hợp lệ được giữ để xem xét mà không chặn nhóm hóa đơn đủ điều kiện khác. |
| Tạm dừng và khôi phục | Tín dụng thấp và các chốt an toàn chuyển tiền vẫn tạm dừng chi tiêu. Theo dõi và đối soát sổ cái tiếp tục. Tiếp tục sẽ xem xét lại cùng kế hoạch được giữ. Giao dịch EVM bị revert trên chuỗi chính tắc, được hai nhà cung cấp độc lập chứng minh, có thể được thay sau phê duyệt rõ ràng trong ngân sách phí còn lại; mã băm và phí gốc vẫn được ghi. Kết quả chưa rõ hoặc giao token không khớp vẫn bị giữ. Sao lưu toàn bộ cơ sở dữ liệu và khóa; đối soát mã băm đã gửi sau khôi phục trước khi cho phép chi trả. |
| Mã định danh và phân trang | Dùng UUID dự án từ Cài đặt dự án và UUID cửa hàng từ Cửa hàng → Cơ bản → ID API. API này trả ID nhà bán hàng/chi trả/tài sản. invoice_id là UUID công khai của hóa đơn. Tài nguyên phân trang trả data và pagination {page,per_page,total,pages}; mặc định 1/25, tối đa 100 dòng. Giá trị tiền chính xác là chuỗi. |
| Phạm vi thông tin xác thực | Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối. |
Quyền Marketplace
marketplace.read · vendors.write · destinations.write · destinations.approve · invoices.write · policies.write · commissions.override · payouts.write · payouts.approve · webhooks.write · reconciliation.write
Trạng thái khoản phân bổ
pending · held · available · reserved · paid · refunding · refunded · shortfall
Trạng thái chi trả
awaiting_approval · queued · funding_gas · sending · confirming · partially_paid · paid · needs_attention · cancelled · expired
Sự kiện sàn thương mại
Bí mật ký Marketplace riêng, dùng cùng header chữ ký Wholly và thuật toán xác minh HMAC nội dung thô như callback hóa đơn. Xác minh dấu thời gian/chữ ký, loại trùng event_id và nhanh chóng trả 2xx. Gửi ít nhất một lần, tối đa tám lần thử; lịch sử có thể gửi lại cùng sự kiện. Sửa endpoint hủy lần gửi cũ chưa gửi thay vì chuyển hướng dữ liệu khách hàng. Quyết toán hóa đơn không có nghĩa đã hoàn tất chi trả nhà bán hàng. Không bao giờ gửi tiền chỉ vì callback bên ngoài yêu cầu.
marketplace.invoice.createdmarketplace.allocations.availablemarketplace.allocations.heldmarketplace.payout.approvedmarketplace.payout.broadcastmarketplace.payout.confirmedmarketplace.payout.partialmarketplace.payout.failedmarketplace.payout.cancelledmarketplace.refund.preparedmarketplace.refund.confirmed
{
"event_id": "11111111-1111-4111-8111-111111111111",
"event_type": "marketplace.payout.confirmed",
"payload_version": 1,
"project_id": "YOUR_PROJECT_ID",
"occurred_at": "2026-10-06T12:00:00Z",
"data": {
"payout_id": "YOUR_PAYOUT_ID",
"asset_id": "YOUR_ASSET_ID",
"amount_atomic": "28800000",
"transactions": [
{
"transaction_id": "EXAMPLE_TRANSACTION_ID",
"explorer_url": "https://mempool.space/tx/EXAMPLE_TRANSACTION_ID"
}
]
}
}Thiết lập thanh toán đa nhà bán hàng · Tạo hóa đơn Marketplace
Lỗi & giới hạn
Xử lý xác thực dữ liệu, hạn mức và thử lại một cách nhất quán.
Kiểm tra trạng thái HTTP và Content-Type trước khi phân tích phản hồi. Với 429, chờ ít nhất Retry-After trước khi thử lại.
| Giới hạn | Chi tiết |
|---|---|
| Tần suất yêu cầu | Hạn mức theo thông tin xác thực: mặc định 120 yêu cầu mỗi phút UTC, cấu hình từ 1 đến 6000 trong Cài đặt → API. Mọi lần đọc và ghi v1 có xác thực, gồm thử lại idempotent và lỗi phân quyền/xác thực dữ liệu sau xác thực danh tính, dùng chung hạn mức trên các tên miền, dự án và tiến trình. Thông tin xác thực không hợp lệ, tuyến bảng điều khiển và trang thanh toán công khai không dùng hạn mức này. |
| Header giới hạn tần suất | Phản hồi v1 có xác thực gồm X-RateLimit-Limit, X-RateLimit-Remaining và X-RateLimit-Reset (giây Unix tại mốc phút UTC tiếp theo). Yêu cầu vượt mức trả JSON 429 rate_limit_exceeded và Retry-After theo giây nguyên. Chờ ít nhất chừng đó và thêm độ trễ ngẫu nhiên khi thử lại. Cửa sổ cố định cho phép đợt yêu cầu dồn tại ranh giới phút; đây không phải bảo đảm số yêu cầu mỗi giây. |
| Nội dung yêu cầu nhà bán hàng | Tối đa 32 KiB tại bộ định tuyến ứng dụng. Lớp biên có thể từ chối yêu cầu quá lớn trước khi tạo cấu trúc lỗi JSON. |
| Danh sách hóa đơn | limit mặc định 50 và chấp nhận 1–100; offset chấp nhận 0–1,000,000. Tìm kiếm tối đa 100 ký tự. Kết quả mới nhất trước và có metadata total/has_more. |
| Phương thức cửa hàng | Tối đa 64 lựa chọn tài sản mỗi cửa hàng, đủ cho cả 30 chuỗi gốc cùng danh mục token đã xác minh có giới hạn. Chính sách dự án, khả năng máy quét và ví chuỗi sẵn sàng đã sao lưu vẫn là điều kiện tạo hóa đơn. |
| Khám phá token | Giới hạn ứng viên mặc định 50 và chấp nhận 1–100. Kết quả khám phá chưa phải tài sản thanh toán cho đến khi xác minh trên chuỗi thành công. |
| Token dự án đã đăng ký | Tối đa 20 tài sản token lưu bền vững mỗi dự án. Tài sản đã đăng ký có thể dùng lại mà không chiếm thêm suất. |
| Tính idempotent | Bắt buộc khi tạo hóa đơn. 1–128 ký tự ASCII hiển thị, không có khoảng trắng; khóa duy nhất theo cửa hàng, và phát lại phải dùng thông tin xác thực gốc cùng nội dung thô chính xác. |
| Metadata | Chỉ đối tượng JSON, tối đa 4,096 byte sau mã hóa và năm cấp lồng nhau. |
| Callback | URL HTTPS công khai tối đa 2,048 byte. Nội dung yêu cầu thông báo giới hạn 256 KiB; payload sự kiện hóa đơn được lưu giữ giới hạn 64 KiB với lịch sử thanh toán có giới hạn. |
| Tài nguyên trang thanh toán | Phản hồi QR SVG là riêng tư và no-store vì thanh toán thiếu làm thay đổi phần tiền còn lại chính xác. Logo PNG có phiên bản được lưu đệm công khai một năm và bất biến. |
| Lớp biên API | Yêu cầu tới upstream API được quản lý có thời gian chờ đọc 30 giây. Thiết kế bên gọi với thời gian chờ rõ ràng ngắn hơn thời lượng cho phép của tác vụ. |
| Lỗi không phải JSON | Trích xuất UUID/truy vấn sai định dạng, phương thức sai và giới hạn độ dài 32 KiB có thể trả văn bản/phản hồi rỗng của framework. Đường dẫn /v1 không xác định hiện trả HTML bảng điều khiển 404; xác thực trạng thái và Content-Type trước khi phân tích. |
Tham chiếu lỗi
| HTTP | Mã lỗi | Ý nghĩa |
|---|---|---|
| 400 | invalid_reconciliation_action | Trạng thái ngoại lệ, lý do, tìm kiếm hoặc bộ lọc trang lịch sử không hợp lệ. |
| 500 | reconciliation_unavailable | Không thể tải hàng đợi ngoại lệ hoặc bằng chứng. Thử đọc lại với thời gian chờ tăng dần. |
| 402 | billing_required | Mỗi hóa đơn mới cần tài khoản tín dụng ghép cặp đã xác minh và quyền cho phép còn hiệu lực. Thiếu tín dụng trả trước không chặn tạo hóa đơn hay nhận thanh toán: thay vào đó IPN, webhook và Sweep tạm dừng, còn phí vẫn tích lũy. Việc tạo vẫn bị chặn với tài khoản bị đình chỉ, xác minh thanh toán dịch vụ hết hạn/không hợp lệ, dịch vụ tín dụng không truy cập được hoặc cơ sở tiền pháp định hóa đơn chưa được cho phép. Phí dùng số tiền pháp định gốc của hóa đơn, không dùng tiền mã hóa đã nhận, chênh lệch, tiền thừa hay phí mạng. Số tiền đó và phép quy đổi độc lập được đăng ký trước khi tạo trang thanh toán. Theo dõi hiện có và truy xuất hóa đơn tiếp tục trong sự cố. Sau khi nạp tiền, thông báo xếp hàng tiếp tục trong thời hạn lưu payload thông thường và quy tắc gom tiền đang bật tiếp tục. Kiểm tra Cài đặt → Phí và thử lại lần tạo thất bại bằng cùng Idempotency-Key. |
| 400 | invalid_json | JSON sai định dạng, trường không xác định hoặc nội dung không khớp yêu cầu đã ghi trong tài liệu. |
| 400 | idempotency_key_required | Yêu cầu tạo hóa đơn thiếu Idempotency-Key. |
| 400 | invalid_idempotency_key | Khóa rỗng, quá 128 byte, không phải ASCII, chứa khoảng trắng hoặc byte điều khiển. |
| 400 | invalid_payment_request | Trường được xác thực hoặc phương thức đang hoạt động được chọn đã thất bại. Đọc error.message và error.details.payment_methods (PaymentMethodIssue[]) để biết chính xác nguyên nhân chặn. SDK 2.4.0+ thêm tóm tắt ngoại lệ an toàn có hướng xử lý và hàm hỗ trợ vấn đề; SDK PHP cũ cung cấp getApiMessage(). |
| 400 | invalid_invoice_status | Trạng thái liệt kê nằm ngoài sáu trạng thái hóa đơn được ghi trong tài liệu. |
| 400 | invalid_callback_url | Đích IPN có hiệu lực không vượt qua xác thực HTTPS, địa chỉ công khai, DNS hoặc SSRF. |
| 400 | invalid_wallet_request | Đầu vào chuẩn bị ví/địa chỉ không hợp lệ. |
| 400 | invalid_token_asset | Chuỗi token, truy vấn ứng viên, danh tính CoinGecko, metadata danh mục hoặc đầu vào hợp đồng/mint không hợp lệ. |
| 401 | authentication_required | Token bearer thiếu, sai định dạng, bị tắt, đã luân chuyển hoặc không xác định. |
| 403 | source_ip_denied | Giới hạn IP của thông tin xác thực không gồm địa chỉ nguồn công khai chính xác của yêu cầu. |
| 403 | source_ip_not_allowed | Giới hạn IP nguồn của tên máy chủ loại trừ ứng dụng khách này. Quản trị viên có thể quản lý danh sách cho phép của máy chủ đang hoạt động trong Cài đặt → Hệ thống; chúng áp dụng bổ sung cho giới hạn IP của thông tin xác thực. |
| 503 | source_access_unavailable | Xác minh quyền truy cập tên máy chủ tạm thời không khả dụng. Thử lại sau; khi lỗi, giới hạn sẽ từ chối truy cập để bảo đảm an toàn. |
| 403 / 409 / 500 | merchant_api_access_denied | Phân quyền thất bại: quyền/phạm vi dự án có thể là 403, dự án/cửa hàng bị tắt có thể là 409 và lỗi hệ thống phân quyền phía sau có thể là 500. Ví nhận của Operator chỉ dành cho bảng Operator, không dành cho thông tin xác thực API nhà bán hàng hay MCP, kể cả có quyền dự án rõ ràng từ trước. |
| 403 | project_access_denied | Kiểm tra lại trong giao dịch tại lúc tạo phát hiện thông tin xác thực không còn quyền truy cập dự án. |
| 404 | invoice_not_found | Không có hóa đơn với ID công khai đó trong dự án được cấp quyền, hoặc trang thanh toán không thể hiển thị nó. |
| 404 | payment_resource_not_found | Dự án, cửa hàng, tài sản hoặc ví cần trong lúc chuẩn bị hóa đơn không còn tồn tại. |
| 404 | token_candidate_not_found | Dự án không khả dụng hoặc token không còn trong danh mục khám phá khớp hiện tại. |
| 409 | idempotency_conflict | Khóa theo phạm vi cửa hàng đã tồn tại và thông tin xác thực khác hoặc byte nội dung thô yêu cầu khác. |
| 409 | store_unavailable | Dự án/cửa hàng bị tắt hoặc không khả dụng. |
| 409 | no_ready_payment_methods | Không phương thức cửa hàng nào sẵn sàng. Đọc error.message và error.details.payment_methods để biết chain_slug, asset_ticker và reason_code. Sao lưu/kích hoạt ví, adapter đã cài và định giá phải hợp lệ. Từ 6.0.6, thời gian chờ máy quét, kiểm tra tình trạng thất bại hoặc cũ và thiếu số nguồn đồng thuận không chặn tạo hóa đơn. |
| 409 | payment_method_unavailable | Phương thức được chọn trở nên không khả dụng trong kiểm tra lại nguyên tử tại lúc tạo. |
| 409 | store_payment_method_not_selected | Đã yêu cầu ghi đè xác nhận cửa hàng cho tài sản hiện không được cửa hàng đó chọn. |
| 409 | wallet_unavailable | Ví thanh toán trở nên không khả dụng trong kiểm tra lại nguyên tử tại lúc tạo. |
| 409 | ipn_secret_required | Có URL IPN hiệu lực nhưng cửa hàng không có bí mật ký IPN. |
| 409 | payment_resource_not_ready | Tài sản thanh toán hoặc ví bắt buộc bị tắt, chưa sao lưu, đang chờ bằng chứng kích hoạt tài khoản dùng chung, đã cạn khả năng cấp phát hoặc chưa sẵn sàng vì lý do khác. |
| 409 | account_activation_unverified | Không chứng minh được kích hoạt tài khoản XRP Ledger hoặc Stellar qua số endpoint mainnet khỏe mạnh đã cấu hình (mặc định 2, tùy chọn 1); nạp đúng tài khoản rồi thử xác minh lại. |
| 400 | invalid_monero_wallet_rpc | Endpoint HTTPS, địa chỉ chính mainnet chính xác, nhãn hoặc đầu vào xác thực Digest/Basic/header đầy đủ không hợp lệ. |
| 404 | monero_wallet_rpc_not_found | Liên kết wallet-RPC Monero theo phạm vi dự án không tồn tại. |
| 409 | monero_wallet_rpc_not_ready | Tài sản Monero, đồng thuận hai daemon, liên kết bất biến hoặc xác nhận rõ về sao lưu/chỉ xem chưa sẵn sàng. |
| 409 | monero_wallet_rpc_unavailable | Tạo hóa đơn cần liên kết wallet-RPC Monero dự án đang hoạt động, đã xác minh và xác nhận, cùng thông tin xác thực phía máy chủ hợp lệ. |
| 503 | lightning_unavailable | Phương thức sẵn sàng duy nhất của cửa hàng là Lightning và không xác minh được ví hoặc báo giá. Thử lại bằng cùng khóa idempotency. Khi có phương thức trên chuỗi khác sẵn sàng, phương thức Lightning không khả dụng sẽ được bỏ qua. |
| 422 | monero_wallet_rpc_verification_failed | Xác minh ví chính xác, ghim HTTPS, đồng bộ, đồng thuận daemon mainnet hoặc bằng chứng cổng từ chối phương thức đã thất bại. |
| 503 | monero_wallet_rpc_failed | wallet-RPC chỉ xem bên ngoài không thể cấp phát và đọc lại địa chỉ phụ hóa đơn một cách an toàn; không tạo địa chỉ dự phòng giả. |
| 409 | token_chain_not_ready | Tài sản gốc của chuỗi bị tắt, ánh xạ khám phá thay đổi trong lúc xác minh hoặc dự án đã đạt mức tối đa hiện tại là 20 tài sản token đăng ký. |
| 503 | dex_price_unavailable | Nhà cung cấp DEX không khả dụng, bận, bị giới hạn tần suất, trả phản hồi cũ hoặc dữ liệu sai định dạng. Thử lại sau một phút; định giá cố định vẫn dùng được. |
| 422 | invalid_dex_price | Kết hợp chế độ giá không hợp lệ hoặc pool được chọn không thể cung cấp giá đủ điều kiện cho đúng hợp đồng. Chọn pool khác hoặc giá USD cố định. |
| 422 | token_verification_failed | Mọi nút đủ điều kiện đều thất bại khi xác minh danh tính chuỗi, mã hợp đồng, số chữ số thập phân, truy vấn số dư hoặc mint. |
| 422 | invalid_store_confirmation_policy | Ghi đè của cửa hàng không dùng được với chế độ hoàn tất này, nằm ngoài giới hạn theo chuỗi được trả về hoặc yêu cầu chấp nhận không xác nhận không được hỗ trợ. |
| 409 | invoice_not_payable | Hóa đơn trên trang thanh toán đã ở trạng thái kết thúc hoặc đã qua hạn thanh toán. |
| 409 | invoice_payment_method_locked | Một khoản thanh toán hợp lệ đã chọn tài sản khác; tiếp tục với active_payment_method_id. |
| 409 | payment_method_not_payable | Phương thức được chọn đã hoàn tất hoặc không còn chấp nhận thêm thanh toán. |
| 422 | payment_qr_unavailable | Yêu cầu thanh toán quá lớn để mã hóa thành hình QR SVG. |
| 503 | payment_rates_unavailable | Không có báo giá mới đáng tin cho bất kỳ phương thức thanh toán sẵn sàng nào. |
| 500 | authentication_unavailable | Xác thực bearer không thể đọc hoặc xác thực thông tin xác thực đã lưu một cách an toàn. |
| 429 | rate_limit_exceeded | Thông tin xác thực này đã dùng hết hạn mức phút UTC hiện tại. Chờ ít nhất Retry-After giây; thử tạo hóa đơn lại bằng cùng khóa idempotency. |
| 500 | database_error / internal_error | Lỗi tạm thời phía máy chủ; thử lại an toàn bằng cùng khóa idempotency. |
Tổng quan API
Chọn endpoint để xem trường, ví dụ và phản hồi.
Hóa đơn
POSTTạo hóa đơn/v1/projects/{project_id}/stores/{store_id}/invoicesGETLiệt kê hóa đơn/v1/projects/{project_id}/invoicesGETTruy xuất hóa đơn/v1/projects/{project_id}/invoices/{invoice_id}GETLiệt kê khoản thanh toán của hóa đơn/v1/projects/{project_id}/invoices/{invoice_id}/paymentsPhương thức thanh toán
GETLiệt kê tài sản thanh toán của dự án/v1/projects/{project_id}/payment-assetsPUTCập nhật chính sách tài sản của dự án/v1/projects/{project_id}/payment-assets/{asset_id}GETDuyệt token thanh toán ứng viên/v1/projects/{project_id}/payment-token-candidatesPOSTXác minh và đăng ký token/v1/projects/{project_id}/payment-token-assetsGETTìm pool DEX cho token tùy chỉnh/v1/projects/{project_id}/payment-token-dex-poolsPOSTThêm hoặc định giá lại token tùy chỉnh/v1/projects/{project_id}/payment-token-assets/customGETLiệt kê phương thức thanh toán của cửa hàng/v1/projects/{project_id}/stores/{store_id}/payment-assetsPUTThay thế phương thức thanh toán của cửa hàng/v1/projects/{project_id}/stores/{store_id}/payment-assetsPUTĐặt chính sách xác nhận cho cửa hàng/v1/projects/{project_id}/stores/{store_id}/payment-assets/{asset_id}/confirmation-policyVí
GETLiệt kê ví và số dư của dự án/v1/projects/{project_id}/walletsĐối soát
GETLiệt kê ngoại lệ thanh toán/v1/projects/{project_id}/reconciliationGETĐọc bằng chứng đối soát/v1/projects/{project_id}/reconciliation/{invoice_id}API sàn thương mại
GETKhả năng/v1/marketplace/capabilitiesGETBáo cáo sàn thương mại/v1/marketplace/overviewGETCài đặt dự án/v1/marketplace/settingsPOSTLưu cài đặt dự án/v1/marketplace/settingsGETLiệt kê nhà bán hàng/v1/marketplace/vendorsPOSTTạo nhà bán hàng/v1/marketplace/vendorsGETLấy nhà bán hàng/v1/marketplace/vendors/{vendor_id}POSTCập nhật nhà bán hàng/v1/marketplace/vendors/{vendor_id}/updatePOSTLưu trữ nhà bán hàng/v1/marketplace/vendors/{vendor_id}/archiveGETĐích nhận của nhà bán hàng/v1/marketplace/vendors/{vendor_id}/destinationsPOSTThêm đích chi trả/v1/marketplace/vendors/{vendor_id}/destinationsPOSTPhê duyệt đích nhận/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/approvePOSTVô hiệu hóa đích nhận/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/disableGETSố dư nhà bán hàng/v1/marketplace/vendors/{vendor_id}/balancesGETHóa đơn sàn thương mại/v1/marketplace/invoicesPOSTTạo hóa đơn nhiều nhà bán hàng/v1/marketplace/invoicesGETHóa đơn và khoản phân bổ/v1/marketplace/invoices/{invoice_id}GETBằng chứng thanh toán hóa đơn/v1/marketplace/invoices/{invoice_id}/paymentsGETKhoản phân bổ hóa đơn/v1/marketplace/invoices/{invoice_id}/allocationsPOSTHủy hóa đơn chưa thanh toán/v1/marketplace/invoices/{invoice_id}/cancelPOSTGiữ khoản phân bổ/v1/marketplace/invoices/{invoice_id}/allocations/holdPOSTXem xét và giải phóng khoản phân bổ/v1/marketplace/invoices/{invoice_id}/allocations/releasePOSTGán lại đích nhận chưa thanh toán/v1/marketplace/invoices/{invoice_id}/allocations/{allocation_id}/destinationPOSTChuẩn bị hoàn tiền toàn bộ/v1/marketplace/invoices/{invoice_id}/refundGETTìm khoản phân bổ chi trả/v1/marketplace/allocationsGETSố dư sổ cái dự án/v1/marketplace/balancesGETNhật ký bất biến/v1/marketplace/ledgerGETLịch sử chi trả/v1/marketplace/payoutsPOSTXem trước kế hoạch phân bổ/v1/marketplace/payouts/previewPOSTChuẩn bị chi trả/v1/marketplace/payoutsGETChi tiết chi trả/v1/marketplace/payouts/{payout_id}POSTPhê duyệt và gửi/v1/marketplace/payouts/{payout_id}/approvePOSTXem xét và tiếp tục chi trả/v1/marketplace/payouts/{payout_id}/resumePOSTHủy công việc chưa ký/v1/marketplace/payouts/{payout_id}/cancelGETChính sách chi trả tự động/v1/marketplace/policiesPOSTỦy quyền chính sách chi trả/v1/marketplace/policiesGETWebhook sàn thương mại/v1/marketplace/webhooksPOSTTạo webhook sàn thương mại/v1/marketplace/webhooksPOSTCập nhật webhook sàn thương mại/v1/marketplace/webhooks/{webhook_id}/updatePOSTVô hiệu hóa webhook sàn thương mại/v1/marketplace/webhooks/{webhook_id}/disableGETSự kiện sàn thương mại/v1/marketplace/eventsGETĐọc sự kiện được lưu giữ/v1/marketplace/events/{event_id}GETLịch sử gửi của sàn thương mại/v1/marketplace/webhook-deliveriesGETChi tiết lần gửi/v1/marketplace/webhook-deliveries/{delivery_id}POSTGửi lại cùng sự kiện/v1/marketplace/webhook-deliveries/{delivery_id}/resendAPI Operator
GETKhả năng/v1/operator/capabilitiesGETTình trạng/v1/operator/healthGETLiệt kê nhà bán hàng/v1/operator/merchantsPOSTTạo nhà bán hàng/v1/operator/merchantsGETLấy nhà bán hàng/v1/operator/merchants/{merchant_id}POSTCập nhật nhà bán hàng/v1/operator/merchants/{merchant_id}GETLiệt kê người dùng/v1/operator/merchants/{merchant_id}/usersPOSTTạo người dùng/v1/operator/merchants/{merchant_id}/usersGETLấy người dùng/v1/operator/merchants/{merchant_id}/users/{user_id}POSTCập nhật người dùng/v1/operator/merchants/{merchant_id}/users/{user_id}POSTĐặt mật khẩu người dùng/v1/operator/merchants/{merchant_id}/users/{user_id}/passwordPOSTThu hồi phiên của người dùng/v1/operator/merchants/{merchant_id}/users/{user_id}/revoke-sessionsGETLiệt kê lời mời/v1/operator/merchants/{merchant_id}/invitationsPOSTTạo lời mời/v1/operator/merchants/{merchant_id}/invitationsGETLấy lời mời/v1/operator/invitations/{invitation_id}POSTGửi lại lời mời/v1/operator/invitations/{invitation_id}/resendPOSTThu hồi lời mời/v1/operator/invitations/{invitation_id}/revokeGETLấy tín dụng/v1/operator/merchants/{merchant_id}/creditsGETLiệt kê sổ cái tín dụng/v1/operator/merchants/{merchant_id}/credits/ledgerPOSTĐiều chỉnh tín dụng/v1/operator/merchants/{merchant_id}/credits/adjustmentsGETLiệt kê lần nạp/v1/operator/merchants/{merchant_id}/topupsPOSTTạo lần nạp/v1/operator/merchants/{merchant_id}/topupsGETLấy lần nạp/v1/operator/merchants/{merchant_id}/topups/{topup_id}GETBáo cáo/v1/operator/reportsGETLiệt kê nhật ký kiểm toán/v1/operator/auditGETLiệt kê sự kiện/v1/operator/eventsGETLiệt kê webhook/v1/operator/webhooksPOSTTạo webhook/v1/operator/webhooksPOSTCập nhật webhook/v1/operator/webhooks/{webhook_id}POSTLuân chuyển bí mật webhook/v1/operator/webhooks/{webhook_id}/rotateGETLiệt kê lần gửi webhook/v1/operator/webhooks/{webhook_id}/deliveriesGETLiệt kê dự án/v1/operator/merchants/{merchant_id}/projectsPOSTTạo dự án/v1/operator/merchants/{merchant_id}/projectsGETLấy dự án/v1/operator/merchants/{merchant_id}/projects/{project_id}POSTCập nhật dự án/v1/operator/merchants/{merchant_id}/projects/{project_id}GETLiệt kê cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesPOSTTạo cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesGETLấy cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}POSTCập nhật cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}GETLấy giao diện cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearancePOSTCập nhật giao diện cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearanceGETLiệt kê tài sản thanh toán của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsPOSTCập nhật tài sản thanh toán của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsGETLiệt kê webhook của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksPOSTTạo webhook của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksPOSTCập nhật webhook của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooks/{webhook_id}GETLiệt kê hóa đơn/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoicesGETLấy hóa đơn/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoices/{invoice_id}GETLiệt kê ví/v1/operator/merchants/{merchant_id}/projects/{project_id}/walletsGETLiệt kê địa chỉ ví/v1/operator/merchants/{merchant_id}/projects/{project_id}/wallets/{wallet_id}/addressesGETLiệt kê thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentialsPOSTTạo thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentialsPOSTCập nhật thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}POSTLuân chuyển thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/rotatePOSTThu hồi thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/revokePOSTKiểm tra token lời mời/v1/onboarding/invitations/checkPOSTChấp nhận lời mời hoặc đặt lại mật khẩu/v1/onboarding/invitations/acceptTrang thanh toán
GETKhung trang thanh toán/GETTrang thanh toán được lưu trữ/invoice/{invoice_id}GETHóa đơn an toàn cho trang thanh toán/checkout-api/invoices/{invoice_id}GETXem trước trang thanh toán của cửa hàng/invoice/preview/{project_id}GETDữ liệu xem trước trang thanh toán/checkout-api/previews/{project_id}GETHình ảnh trang thanh toán của cửa hàng/checkout-api/invoices/{invoice_id}/appearance-images/{kind}/{revision}/image.pngGETHình ảnh xem trước cửa hàng/checkout-api/previews/{project_id}/stores/{store_id}/appearance-images/{kind}/{revision}/image.pngGETLogo xem trước có phiên bản/checkout-api/previews/{project_id}/logo/{revision}/image.pngGETHình ảnh QR thanh toán/checkout-api/invoices/{invoice_id}/payment-methods/{intent_id}/qr.svgGETLogo trang thanh toán có phiên bản/checkout-api/invoices/{invoice_id}/logo/{revision}/image.pngDịch vụ
GETKhám phá dịch vụ API/GETTình trạng dịch vụ/healthzGETKhả năng/v1/operator/capabilitiesChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/capabilities" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/capabilities", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/capabilities");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/capabilities",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"api_version": "v1",
"operator_version": "7.4.0",
"scopes": [
"health.read"
],
"all_merchants": false,
"merchant_ids": [
"11111111-1111-4111-8111-111111111111"
],
"onboarding": [
"direct",
"invitation"
],
"write_methods": [
"POST"
],
"idempotency_required": true
}Trường phản hồi
Ghi chú sử dụng
- Cần health.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETTình trạng/v1/operator/healthChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/health" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/health", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/health");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/health",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"version": "7.4.0",
"nodes": []
}Trường phản hồi
Ghi chú sử dụng
- Cần health.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê nhà bán hàng/v1/operator/merchantsChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần merchants.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTTạo nhà bán hàng/v1/operator/merchantsĐọc + ghi
Tạo nguyên tử nhà bán hàng được lưu trữ và quản trị viên đầu tiên, trực tiếp bằng mật khẩu hoặc qua lời mời.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Example shop",
"email": "admin@example.test",
"onboarding": "direct",
"password": "REPLACE_WITH_A_UNIQUE_TEMPORARY_PASSWORD",
"require_password_change": true,
"currency": "EUR",
"starting_credit": "0",
"external_id": "customer-1042"
}'// 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 operation.
const body = `{
"name": "Example shop",
"email": "admin@example.test",
"onboarding": "direct",
"password": "REPLACE_WITH_A_UNIQUE_TEMPORARY_PASSWORD",
"require_password_change": true,
"currency": "EUR",
"starting_credit": "0",
"external_id": "customer-1042"
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"name": "Example shop",
"email": "admin@example.test",
"onboarding": "direct",
"password": "REPLACE_WITH_A_UNIQUE_TEMPORARY_PASSWORD",
"require_password_change": true,
"currency": "EUR",
"starting_credit": "0",
"external_id": "customer-1042"
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"name": "Example shop",
"email": "admin@example.test",
"onboarding": "direct",
"password": "REPLACE_WITH_A_UNIQUE_TEMPORARY_PASSWORD",
"require_password_change": true,
"currency": "EUR",
"starting_credit": "0",
"external_id": "customer-1042"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants",
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))Nội dung yêu cầu
onboardingdirect | invitationbắt buộcdirect cần password, không gửi email mời. invitation bỏ password.
passwordstring · direct only12–128 ký tự (tối đa 512 byte UTF-8); không bao giờ được trả về hay gửi email. Dùng require_password_change cho mật khẩu tạm thời.
require_password_changebooleantùy chọnYêu cầu mật khẩu mới khi đăng nhập lần đầu. Mọi tài khoản được cấp trực tiếp phải thừa nhận việc lưu ký ví tại bên lưu trữ.
currencyfiat codetùy chọnLoại tiền tài khoản trả trước; mặc định là tiền theo khu vực và không thể đổi về sau.
fee_bpsintegertùy chọn0–10000; 100 nghĩa là 1%. Dùng mặc định nhà vận hành khi bỏ qua. Cần fees.write.
starting_creditdecimal stringtùy chọnKhoản cấp cục bộ một lần chính xác. Khác không cần credits.write. Không nạp lại số dư bản cài đặt của nhà vận hành.
send_invitation_emailbooleantùy chọnChỉ lời mời. Cần SMTP đã cấu hình; phản hồi phân biệt relay chấp nhận với tạo tài khoản.
Phản hồi 201 or 200 application/json
Phản hồi ví dụ
{
"merchant_id": "11111111-1111-4111-8111-111111111111",
"user_id": "22222222-2222-4222-8222-222222222222",
"merchant": {
"id": "11111111-1111-4111-8111-111111111111",
"name": "Example shop",
"currency": "EUR",
"balance": "0"
},
"onboarding": "direct",
"access_link": null,
"email_delivery": {
"status": "not_requested"
},
"custody_acceptance_required": true
}Trường phản hồi
Ghi chú sử dụng
- Cần merchants.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Cần quyền truy cập nhà bán hàng toàn cục. Ghi đè phí rõ ràng còn cần fees.write; starting_credit khác không cần credits.write. Tiếp nhận qua lời mời còn cần invitations.write. Không tự đăng nhập, không vượt Basic Auth, không ghi có hồi tố khi thử lại.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLấy nhà bán hàng/v1/operator/merchants/{merchant_id}Chỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "11111111-1111-4111-8111-111111111111",
"name": "Example shop",
"currency": "EUR",
"balance": "10",
"fee_bps": 300,
"enabled": true,
"payments_paused": false,
"external_id": "customer-1042"
}Trường phản hồi
Ghi chú sử dụng
- Cần merchants.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTCập nhật nhà bán hàng/v1/operator/merchants/{merchant_id}Đọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"payments_paused": true
}'// 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 operation.
const body = `{
"payments_paused": true
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"payments_paused": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"payments_paused": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID",
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))Nội dung yêu cầu
namefieldstùy chọnTắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.Chi tiết
Tắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.
enabledfieldstùy chọnTắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.Chi tiết
Tắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.
payments_pausedfieldstùy chọnTắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.Chi tiết
Tắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.
fee_bpsfieldstùy chọnTắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.Chi tiết
Tắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.
external_idfieldstùy chọnTắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.Chi tiết
Tắt sẽ thu hồi phiên. payments_paused chặn hóa đơn mới, không chặn quét thanh toán hiện có. Sửa phí cần fees.write và áp dụng cho hóa đơn tương lai; không thể đổi loại tiền tài khoản.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "11111111-1111-4111-8111-111111111111",
"name": "Example shop",
"currency": "EUR",
"balance": "10",
"fee_bps": 300,
"enabled": true,
"payments_paused": false
}Trường phản hồi
Ghi chú sử dụng
- Cần merchants.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê người dùng/v1/operator/merchants/{merchant_id}/usersChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần users.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTTạo người dùng/v1/operator/merchants/{merchant_id}/usersĐọc + ghi
Thêm quản trị viên nhà bán hàng hoặc người dùng giới hạn ở dự án được chọn.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "staff@example.test",
"display_name": "Store team",
"onboarding": "invitation",
"access_level": "projects",
"project_ids": [
"11111111-1111-4111-8111-111111111111"
],
"send_invitation_email": false
}'// 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 operation.
const body = `{
"email": "staff@example.test",
"display_name": "Store team",
"onboarding": "invitation",
"access_level": "projects",
"project_ids": [
"11111111-1111-4111-8111-111111111111"
],
"send_invitation_email": false
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"email": "staff@example.test",
"display_name": "Store team",
"onboarding": "invitation",
"access_level": "projects",
"project_ids": [
"11111111-1111-4111-8111-111111111111"
],
"send_invitation_email": false
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"email": "staff@example.test",
"display_name": "Store team",
"onboarding": "invitation",
"access_level": "projects",
"project_ids": [
"11111111-1111-4111-8111-111111111111"
],
"send_invitation_email": false
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users",
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))Nội dung yêu cầu
access_leveladmin | projectstùy chọnadmin chỉ là quản trị viên nhà bán hàng này, không bao giờ là quản trị viên bản cài đặt/nhà vận hành.
project_ids[]UUID[]Chỉ dự án thuộc nhà bán hàng. Bắt buộc chọn với quyền truy cập giới hạn dự án; không bao giờ xuyên tài khoản thuê.
Phản hồi 201 or 200 application/json
Phản hồi ví dụ
{
"user": {
"id": "22222222-2222-4222-8222-222222222222",
"merchant_id": "11111111-1111-4111-8111-111111111111",
"email": "admin@example.test",
"display_name": "Shop administrator",
"access_level": "admin",
"project_ids": [],
"enabled": true,
"password_setup_required": false,
"custody_acceptance_required": true,
"password_change_required": true
},
"user_id": "22222222-2222-4222-8222-222222222222",
"access_link": null,
"email_delivery": {
"status": "not_requested"
},
"merchant_id": "11111111-1111-4111-8111-111111111111"
}Trường phản hồi
userobject
user_idstringaccess_linkJSON | nullmerchant_idstringGhi chú sử dụng
- Cần users.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLấy người dùng/v1/operator/merchants/{merchant_id}/users/{user_id}Chỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "22222222-2222-4222-8222-222222222222",
"merchant_id": "11111111-1111-4111-8111-111111111111",
"email": "admin@example.test",
"display_name": "Shop administrator",
"access_level": "admin",
"project_ids": [],
"enabled": true,
"password_setup_required": false,
"custody_acceptance_required": true,
"password_change_required": true
}Trường phản hồi
Ghi chú sử dụng
- Cần users.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTCập nhật người dùng/v1/operator/merchants/{merchant_id}/users/{user_id}Đọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"display_name": "Store manager"
}'// 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 operation.
const body = `{
"display_name": "Store manager"
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"display_name": "Store manager"
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"display_name": "Store manager"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID",
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))Nội dung yêu cầu
emailfieldstùy chọnCập nhật trường được cung cấp; vẫn bảo vệ quản trị viên cuối cùng. Mật khẩu có thao tác users.security riêng.
display_namefieldstùy chọnCập nhật trường được cung cấp; vẫn bảo vệ quản trị viên cuối cùng. Mật khẩu có thao tác users.security riêng.
enabledfieldstùy chọnCập nhật trường được cung cấp; vẫn bảo vệ quản trị viên cuối cùng. Mật khẩu có thao tác users.security riêng.
access_levelfieldstùy chọnCập nhật trường được cung cấp; vẫn bảo vệ quản trị viên cuối cùng. Mật khẩu có thao tác users.security riêng.
project_idsfieldstùy chọnCập nhật trường được cung cấp; vẫn bảo vệ quản trị viên cuối cùng. Mật khẩu có thao tác users.security riêng.
default_timezonefieldstùy chọnCập nhật trường được cung cấp; vẫn bảo vệ quản trị viên cuối cùng. Mật khẩu có thao tác users.security riêng.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "22222222-2222-4222-8222-222222222222",
"merchant_id": "11111111-1111-4111-8111-111111111111",
"email": "admin@example.test",
"display_name": "Shop administrator",
"access_level": "admin",
"project_ids": [],
"enabled": true,
"password_setup_required": false,
"custody_acceptance_required": true,
"password_change_required": true
}Trường phản hồi
Ghi chú sử dụng
- Cần users.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTĐặt mật khẩu người dùng/v1/operator/merchants/{merchant_id}/users/{user_id}/passwordĐọc + ghi
Đặt mật khẩu tài khoản được lưu trữ và thu hồi phiên. Giữ TOTP hiện có.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/password" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"password": "REPLACE_WITH_A_NEW_UNIQUE_PASSWORD",
"require_password_change": true
}'// 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 operation.
const body = `{
"password": "REPLACE_WITH_A_NEW_UNIQUE_PASSWORD",
"require_password_change": true
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/password", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"password": "REPLACE_WITH_A_NEW_UNIQUE_PASSWORD",
"require_password_change": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/password");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"password": "REPLACE_WITH_A_NEW_UNIQUE_PASSWORD",
"require_password_change": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/password",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"user_id": "11111111-1111-4111-8111-111111111111",
"sessions_revoked": true,
"totp_preserved": true
}Trường phản hồi
Ghi chú sử dụng
- Cần users.security; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTThu hồi phiên của người dùng/v1/operator/merchants/{merchant_id}/users/{user_id}/revoke-sessionsĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/revoke-sessions" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{}'// 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 operation.
const body = `{}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/revoke-sessions", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/revoke-sessions");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/users/YOUR_USER_ID/revoke-sessions",
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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"user_id": "11111111-1111-4111-8111-111111111111",
"sessions_revoked": true,
"totp_preserved": true
}Trường phản hồi
Ghi chú sử dụng
- Cần users.security; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê lời mời/v1/operator/merchants/{merchant_id}/invitationsChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần invitations.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTTạo lời mời/v1/operator/merchants/{merchant_id}/invitationsĐọc + ghi
Tạo hoặc thay liên kết mời hay đặt lại mật khẩu dùng một lần.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"user_id": "11111111-1111-4111-8111-111111111111",
"send_email": false
}'// 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 operation.
const body = `{
"user_id": "11111111-1111-4111-8111-111111111111",
"send_email": false
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"user_id": "11111111-1111-4111-8111-111111111111",
"send_email": false
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"user_id": "11111111-1111-4111-8111-111111111111",
"send_email": false
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/invitations",
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))Nội dung yêu cầu
user_idUUID, booleanCấp/thay liên kết dùng một lần cho tài khoản hiện có. Người dùng đã kích hoạt nhận liên kết đặt lại một giờ và cần users.security.
send_emailUUID, booleanCấp/thay liên kết dùng một lần cho tài khoản hiện có. Người dùng đã kích hoạt nhận liên kết đặt lại một giờ và cần users.security.
new user fieldsalternative to user_idDùng email, display_name, access_level và project_ids để tạo người dùng được mời; cần users.write.
Phản hồi 201 or 200 application/json
Phản hồi ví dụ
{
"user_id": "22222222-2222-4222-8222-222222222222",
"email": "admin@example.test",
"kind": "invitation",
"expires_at": "2026-10-03T12:00:00Z",
"url": "https://merchant.example.com/account-access.html#token=YOUR_PRIVATE_INVITATION_TOKEN"
}Trường phản hồi
Ghi chú sử dụng
- Cần invitations.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLấy lời mời/v1/operator/invitations/{invitation_id}Chỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
invitation_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "44444444-4444-4444-8444-444444444444",
"user_id": "22222222-2222-4222-8222-222222222222",
"merchant_id": "11111111-1111-4111-8111-111111111111",
"kind": "invitation",
"status": "pending",
"created_at": "2026-10-01T12:00:00Z",
"expires_at": "2026-10-03T12:00:00Z"
}Trường phản hồi
Ghi chú sử dụng
- Cần invitations.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTGửi lại lời mời/v1/operator/invitations/{invitation_id}/resendĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
invitation_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/resend" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"send_email": false
}'// 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 operation.
const body = `{
"send_email": false
}`;
const response = await fetch("https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/resend", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"send_email": false
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/resend");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"send_email": false
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/resend",
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))Nội dung yêu cầu
send_emailbooleantùy chọnThay token trước, không bao giờ thêm tín dụng. Trả liên kết mới tạo một lần. Tài khoản đã kích hoạt cần users.security.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"user_id": "22222222-2222-4222-8222-222222222222",
"email": "admin@example.test",
"kind": "invitation",
"expires_at": "2026-10-03T12:00:00Z",
"url": "https://merchant.example.com/account-access.html#token=YOUR_PRIVATE_INVITATION_TOKEN"
}Trường phản hồi
Ghi chú sử dụng
- Cần invitations.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTThu hồi lời mời/v1/operator/invitations/{invitation_id}/revokeĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
invitation_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/revoke" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{}'// 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 operation.
const body = `{}`;
const response = await fetch("https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/revoke", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/revoke");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/invitations/YOUR_INVITATION_ID/revoke",
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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"revoked": true,
"invitation_id": "44444444-4444-4444-8444-444444444444"
}Trường phản hồi
Ghi chú sử dụng
- Cần invitations.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLấy tín dụng/v1/operator/merchants/{merchant_id}/creditsChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "11111111-1111-4111-8111-111111111111",
"name": "Example shop",
"currency": "EUR",
"balance": "10",
"fee_bps": 300,
"enabled": true,
"payments_paused": false,
"external_id": "customer-1042"
}Trường phản hồi
Ghi chú sử dụng
- Cần credits.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê sổ cái tín dụng/v1/operator/merchants/{merchant_id}/credits/ledgerChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
qtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/ledger" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/ledger", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/ledger");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/ledger",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần credits.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTĐiều chỉnh tín dụng/v1/operator/merchants/{merchant_id}/credits/adjustmentsĐọc + ghi
Thêm khoản cấp hoặc điều chỉnh có lý do vào sổ cái trả trước của nhà bán hàng này.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/adjustments" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"amount": "10.00",
"note": "Promotional credit",
"request_id": "11111111-1111-4111-8111-111111111111"
}'// 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 operation.
const body = `{
"amount": "10.00",
"note": "Promotional credit",
"request_id": "11111111-1111-4111-8111-111111111111"
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/adjustments", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"amount": "10.00",
"note": "Promotional credit",
"request_id": "11111111-1111-4111-8111-111111111111"
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/adjustments");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"amount": "10.00",
"note": "Promotional credit",
"request_id": "11111111-1111-4111-8111-111111111111"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/credits/adjustments",
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))Nội dung yêu cầu
amountsigned decimal stringbắt buộcKhoản cấp dương hoặc điều chỉnh âm, tối đa sáu chữ số thập phân theo tiền tín dụng nhà bán hàng. Không phải chuyển tiền trên chuỗi.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"balance": "25"
}Trường phản hồi
balancestringGhi chú sử dụng
- Cần credits.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê lần nạp/v1/operator/merchants/{merchant_id}/topupsChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần topups.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTTạo lần nạp/v1/operator/merchants/{merchant_id}/topupsĐọc + ghi
Tạo trang thanh toán nạp tín dụng trả trước; không bao giờ tự đánh dấu đã thanh toán.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"amount": "25.00",
"request_id": "11111111-1111-4111-8111-111111111111"
}'// 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 operation.
const body = `{
"amount": "25.00",
"request_id": "11111111-1111-4111-8111-111111111111"
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"amount": "25.00",
"request_id": "11111111-1111-4111-8111-111111111111"
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"amount": "25.00",
"request_id": "11111111-1111-4111-8111-111111111111"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups",
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))Nội dung yêu cầu
Phản hồi 201 or 200 application/json
Phản hồi ví dụ
{
"id": "44444444-4444-4444-8444-444444444444",
"invoice_id": "33333333-3333-4333-8333-333333333333",
"checkout_url": "https://pay.example.com/invoice/33333333-3333-4333-8333-333333333333"
}Trường phản hồi
Ghi chú sử dụng
- Cần topups.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLấy lần nạp/v1/operator/merchants/{merchant_id}/topups/{topup_id}Chỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups/YOUR_TOPUP_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups/YOUR_TOPUP_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups/YOUR_TOPUP_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/topups/YOUR_TOPUP_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "44444444-4444-4444-8444-444444444444",
"merchant_id": "11111111-1111-4111-8111-111111111111",
"invoice_id": "33333333-3333-4333-8333-333333333333",
"amount": "25",
"currency": "EUR",
"status": "pending",
"invoice_status": "new",
"checkout_url": "https://pay.example.com/invoice/33333333-3333-4333-8333-333333333333"
}Trường phản hồi
Ghi chú sử dụng
- Cần topups.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETBáo cáo/v1/operator/reportsChỉ đọc
Đọc tổng quan tài chính Operator. Cần quyền truy cập mọi nhà bán hàng được lưu trữ.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số truy vấn
periodtùy chọnBộ lọc tài chính. period mặc định last30; dùng custom với start/end dạng YYYY-MM-DD. Chỉ thông tin xác thực có quyền mọi nhà bán hàng.
starttùy chọnBộ lọc tài chính. period mặc định last30; dùng custom với start/end dạng YYYY-MM-DD. Chỉ thông tin xác thực có quyền mọi nhà bán hàng.
endtùy chọnBộ lọc tài chính. period mặc định last30; dùng custom với start/end dạng YYYY-MM-DD. Chỉ thông tin xác thực có quyền mọi nhà bán hàng.
currencytùy chọnBộ lọc tài chính. period mặc định last30; dùng custom với start/end dạng YYYY-MM-DD. Chỉ thông tin xác thực có quyền mọi nhà bán hàng.
merchant_idtùy chọnBộ lọc tài chính. period mặc định last30; dùng custom với start/end dạng YYYY-MM-DD. Chỉ thông tin xác thực có quyền mọi nhà bán hàng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/reports" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/reports", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/reports");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/reports",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"summary": {
"fees": "10",
"costs": "3",
"margin": "7",
"credits": "25",
"pending": 0,
"missing_rates": 0
},
"merchants": [],
"filters": {
"period": "last30",
"currency": "EUR",
"timezone": "UTC"
},
"basis": "first_settlement_latest_net_fees"
}Trường phản hồi
Ghi chú sử dụng
- Cần reports.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Dòng, chi phí và số lượng của doanh nghiệp riêng được loại trước khi tính tổng. Bộ lọc merchant_id doanh nghiệp riêng trả 404. Báo cáo dùng múi giờ bản cài đặt.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê nhật ký kiểm toán/v1/operator/auditChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số truy vấn
merchant_idtùy chọnLọc nhà bán hàng được cho phép, loại sự kiện chính xác (events) hoặc nội dung hành động (audit). Sự kiện được lưu: 30 ngày.
searchtùy chọnLọc nhà bán hàng được cho phép, loại sự kiện chính xác (events) hoặc nội dung hành động (audit). Sự kiện được lưu: 30 ngày.
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/audit" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/audit", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/audit");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/audit",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần audit.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê sự kiện/v1/operator/eventsChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số truy vấn
merchant_idtùy chọnLọc nhà bán hàng được cho phép, loại sự kiện chính xác (events) hoặc nội dung hành động (audit). Sự kiện được lưu: 30 ngày.
event_typetùy chọnLọc nhà bán hàng được cho phép, loại sự kiện chính xác (events) hoặc nội dung hành động (audit). Sự kiện được lưu: 30 ngày.
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/events" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/events", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/events");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/events",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần events.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê webhook/v1/operator/webhooksChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/webhooks" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/webhooks", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/webhooks");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/webhooks",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần events.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTTạo webhook/v1/operator/webhooksĐọc + ghi
Đăng ký sự kiện vòng đời Operator trong tương lai. Không phải webhook thanh toán cửa hàng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/webhooks" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"url": "https://shop.example.test/operator-events",
"events": [
"merchant.created",
"topup.settled"
],
"merchant_ids": [],
"enabled": true
}'// 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 operation.
const body = `{
"url": "https://shop.example.test/operator-events",
"events": [
"merchant.created",
"topup.settled"
],
"merchant_ids": [],
"enabled": true
}`;
const response = await fetch("https://api.example.com/v1/operator/webhooks", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"url": "https://shop.example.test/operator-events",
"events": [
"merchant.created",
"topup.settled"
],
"merchant_ids": [],
"enabled": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/webhooks");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"url": "https://shop.example.test/operator-events",
"events": [
"merchant.created",
"topup.settled"
],
"merchant_ids": [],
"enabled": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/webhooks",
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))Nội dung yêu cầu
urlpublic HTTPS URLbắt buộcKhông có thông tin xác thực, IP riêng hay chuyển hướng. DNS/IP được kiểm tra lại khi gửi.
events[]string[]bắt buộcChọn sự kiện vòng đời trong hướng dẫn Operator, không chọn callback hóa đơn.
merchant_ids[]UUID[]tùy chọnRỗng nghĩa là mọi nhà bán hàng được thông tin xác thực này cho phép. Giới hạn phạm vi hiện tại được kiểm tra lại.
enabledbooleantùy chọnEndpoint tạm dừng giữ lần gửi trong hàng đợi; bật lại tiếp tục công việc được lưu còn hợp lệ.
Phản hồi 201 or 200 application/json
Phản hồi ví dụ
{
"id": "11111111-1111-4111-8111-111111111111",
"signing_secret": "wco_whsec_EXAMPLE_ONLY_SAVE_ONCE"
}Trường phản hồi
Ghi chú sử dụng
- Cần webhooks.write + events.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTCập nhật webhook/v1/operator/webhooks/{webhook_id}Đọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
webhook_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"url": "https://shop.example.test/operator-events",
"events": [
"topup.settled"
],
"merchant_ids": [],
"enabled": false
}'// 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 operation.
const body = `{
"url": "https://shop.example.test/operator-events",
"events": [
"topup.settled"
],
"merchant_ids": [],
"enabled": false
}`;
const response = await fetch("https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"url": "https://shop.example.test/operator-events",
"events": [
"topup.settled"
],
"merchant_ids": [],
"enabled": false
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"url": "https://shop.example.test/operator-events",
"events": [
"topup.settled"
],
"merchant_ids": [],
"enabled": false
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID",
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))Nội dung yêu cầu
urlpublic HTTPS URLbắt buộcKhông có thông tin xác thực, IP riêng hay chuyển hướng. DNS/IP được kiểm tra lại khi gửi.
events[]string[]bắt buộcChọn sự kiện vòng đời trong hướng dẫn Operator, không chọn callback hóa đơn.
merchant_ids[]UUID[]tùy chọnRỗng nghĩa là mọi nhà bán hàng được thông tin xác thực này cho phép. Giới hạn phạm vi hiện tại được kiểm tra lại.
enabledbooleantùy chọnEndpoint tạm dừng giữ lần gửi trong hàng đợi; bật lại tiếp tục công việc được lưu còn hợp lệ.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "44444444-4444-4444-8444-444444444444",
"signing_secret": null
}Trường phản hồi
Ghi chú sử dụng
- Cần webhooks.write + events.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTLuân chuyển bí mật webhook/v1/operator/webhooks/{webhook_id}/rotateĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
webhook_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/rotate" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{}'// 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 operation.
const body = `{}`;
const response = await fetch("https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/rotate", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/rotate");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/rotate",
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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "11111111-1111-4111-8111-111111111111",
"signing_secret": "wco_whsec_EXAMPLE_ONLY_SAVE_ONCE"
}Trường phản hồi
Ghi chú sử dụng
- Cần webhooks.write + events.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê lần gửi webhook/v1/operator/webhooks/{webhook_id}/deliveriesChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
webhook_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/deliveries" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/deliveries", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/deliveries");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/webhooks/YOUR_WEBHOOK_ID/deliveries",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần events.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê dự án/v1/operator/merchants/{merchant_id}/projectsChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTTạo dự án/v1/operator/merchants/{merchant_id}/projectsĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Online shop",
"slug": "online-shop",
"enabled": false
}'// 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 operation.
const body = `{
"name": "Online shop",
"slug": "online-shop",
"enabled": false
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"name": "Online shop",
"slug": "online-shop",
"enabled": false
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"name": "Online shop",
"slug": "online-shop",
"enabled": false
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects",
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))Nội dung yêu cầu
namestringsbắt buộcTên và mã định danh dự án ổn định duy nhất. Tạo ví cục bộ bằng quy trình khởi tạo dự án hiện có, không bao giờ chuyển tiền.
slugstringsbắt buộcTên và mã định danh dự án ổn định duy nhất. Tạo ví cục bộ bằng quy trình khởi tạo dự án hiện có, không bao giờ chuyển tiền.
reporting_timezonetùy chọnenabled mặc định true; nên tạo ở trạng thái tạm dừng và cấu hình cửa hàng trước.
checkout_titletùy chọnenabled mặc định true; nên tạo ở trạng thái tạm dừng và cấu hình cửa hàng trước.
checkout_descriptiontùy chọnenabled mặc định true; nên tạo ở trạng thái tạm dừng và cấu hình cửa hàng trước.
checkout_themetùy chọnenabled mặc định true; nên tạo ở trạng thái tạm dừng và cấu hình cửa hàng trước.
checkout_accent_colortùy chọnenabled mặc định true; nên tạo ở trạng thái tạm dừng và cấu hình cửa hàng trước.
Phản hồi 201 or 200 application/json
Phản hồi ví dụ
{
"id": "33333333-3333-4333-8333-333333333333",
"slug": "example-shop",
"name": "Example shop",
"enabled": false,
"reporting_currency": "EUR",
"reporting_timezone": "Europe/Berlin",
"stores": []
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLấy dự án/v1/operator/merchants/{merchant_id}/projects/{project_id}Chỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "33333333-3333-4333-8333-333333333333",
"slug": "example-shop",
"name": "Example shop",
"enabled": false,
"reporting_currency": "EUR",
"reporting_timezone": "Europe/Berlin",
"stores": []
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTCập nhật dự án/v1/operator/merchants/{merchant_id}/projects/{project_id}Đọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"enabled": true
}'// 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 operation.
const body = `{
"enabled": true
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"enabled": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"enabled": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID",
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))Nội dung yêu cầu
reporting_currencytùy chọnCập nhật một phần. Không thể đổi mã định danh và quyền sở hữu của nhà bán hàng.
reporting_timezonetùy chọnCập nhật một phần. Không thể đổi mã định danh và quyền sở hữu của nhà bán hàng.
checkout_titletùy chọnCập nhật một phần. Không thể đổi mã định danh và quyền sở hữu của nhà bán hàng.
checkout_descriptiontùy chọnCập nhật một phần. Không thể đổi mã định danh và quyền sở hữu của nhà bán hàng.
checkout_themetùy chọnCập nhật một phần. Không thể đổi mã định danh và quyền sở hữu của nhà bán hàng.
checkout_accent_colortùy chọnCập nhật một phần. Không thể đổi mã định danh và quyền sở hữu của nhà bán hàng.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "33333333-3333-4333-8333-333333333333",
"slug": "example-shop",
"name": "Example shop",
"enabled": false,
"reporting_currency": "EUR",
"reporting_timezone": "Europe/Berlin",
"stores": []
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTTạo cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Web checkout",
"slug": "web-checkout",
"default_currency": "EUR",
"enabled": false
}'// 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 operation.
const body = `{
"name": "Web checkout",
"slug": "web-checkout",
"default_currency": "EUR",
"enabled": false
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"name": "Web checkout",
"slug": "web-checkout",
"default_currency": "EUR",
"enabled": false
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"name": "Web checkout",
"slug": "web-checkout",
"default_currency": "EUR",
"enabled": false
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores",
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))Nội dung yêu cầu
default_currencytùy chọnDùng chuỗi thập phân cho tỷ lệ phần trăm. Cửa hàng mới kế thừa giao diện cửa hàng mặc định của dự án.
invoice_expiry_minutestùy chọnDùng chuỗi thập phân cho tỷ lệ phần trăm. Cửa hàng mới kế thừa giao diện cửa hàng mặc định của dự án.
exchange_rate_spread_percenttùy chọnDùng chuỗi thập phân cho tỷ lệ phần trăm. Cửa hàng mới kế thừa giao diện cửa hàng mặc định của dự án.
underpayment_tolerance_percenttùy chọnDùng chuỗi thập phân cho tỷ lệ phần trăm. Cửa hàng mới kế thừa giao diện cửa hàng mặc định của dự án.
enabledtùy chọnCấu hình tài sản được chấp nhận bằng payment-assets; hóa đơn số tiền bằng không mặc định tắt.
is_defaulttùy chọnCấu hình tài sản được chấp nhận bằng payment-assets; hóa đơn số tiền bằng không mặc định tắt.
allow_zero_amount_invoicestùy chọnCấu hình tài sản được chấp nhận bằng payment-assets; hóa đơn số tiền bằng không mặc định tắt.
allow_underpaymentstùy chọnCấu hình tài sản được chấp nhận bằng payment-assets; hóa đơn số tiền bằng không mặc định tắt.
allow_overpaymentstùy chọnCấu hình tài sản được chấp nhận bằng payment-assets; hóa đơn số tiền bằng không mặc định tắt.
allowed_chain_slugstùy chọnCấu hình tài sản được chấp nhận bằng payment-assets; hóa đơn số tiền bằng không mặc định tắt.
ipn_enabledtùy chọnURL IPN và trả về theo quy tắc xác thực URL hiện có. Không có HTML/JavaScript tùy ý.
default_ipn_urltùy chọnURL IPN và trả về theo quy tắc xác thực URL hiện có. Không có HTML/JavaScript tùy ý.
default_redirect_urltùy chọnURL IPN và trả về theo quy tắc xác thực URL hiện có. Không có HTML/JavaScript tùy ý.
default_cancel_urltùy chọnURL IPN và trả về theo quy tắc xác thực URL hiện có. Không có HTML/JavaScript tùy ý.
redirect_automaticallytùy chọnURL IPN và trả về theo quy tắc xác thực URL hiện có. Không có HTML/JavaScript tùy ý.
checkout_languagetùy chọnDùng ngôn ngữ được hỗ trợ và tên miền vai trò đang hoạt động; cấu hình rõ origin được nhúng.
embed_enabledtùy chọnDùng ngôn ngữ được hỗ trợ và tên miền vai trò đang hoạt động; cấu hình rõ origin được nhúng.
allowed_embed_originstùy chọnDùng ngôn ngữ được hỗ trợ và tên miền vai trò đang hoạt động; cấu hình rõ origin được nhúng.
domainstùy chọnDùng ngôn ngữ được hỗ trợ và tên miền vai trò đang hoạt động; cấu hình rõ origin được nhúng.
Phản hồi 201 or 200 application/json
Phản hồi ví dụ
{
"id": "44444444-4444-4444-8444-444444444444",
"project_id": "33333333-3333-4333-8333-333333333333",
"slug": "online",
"name": "Online shop",
"enabled": false,
"default_currency": "EUR",
"invoice_expiry_minutes": 60
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLấy cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}Chỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
store_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "44444444-4444-4444-8444-444444444444",
"project_id": "33333333-3333-4333-8333-333333333333",
"slug": "online",
"name": "Online shop",
"enabled": false,
"default_currency": "EUR",
"invoice_expiry_minutes": 60
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTCập nhật cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}Đọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
store_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"enabled": true
}'// 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 operation.
const body = `{
"enabled": true
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"enabled": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"enabled": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "44444444-4444-4444-8444-444444444444",
"project_id": "33333333-3333-4333-8333-333333333333",
"slug": "online",
"name": "Online shop",
"enabled": false,
"default_currency": "EUR",
"invoice_expiry_minutes": 60
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLấy giao diện cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearanceChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
store_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"revision": 1,
"settings": {
"inherit_default_store": true
},
"effective": {
"title": "Pay securely"
}
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTCập nhật giao diện cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearanceĐọc + ghi
Lưu thiết kế cửa hàng đã xác thực, được bảo vệ bằng phiên bản sửa đổi.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
store_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"revision": 1,
"settings": {
"inherit_default_store": false,
"title": "Pay securely",
"theme": "light"
}
}'// 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 operation.
const body = `{
"revision": 1,
"settings": {
"inherit_default_store": false,
"title": "Pay securely",
"theme": "light"
}
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"revision": 1,
"settings": {
"inherit_default_store": false,
"title": "Pay securely",
"theme": "light"
}
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"revision": 1,
"settings": {
"inherit_default_store": false,
"title": "Pay securely",
"theme": "light"
}
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/checkout-appearance",
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))Nội dung yêu cầu
revisionintegerbắt buộcĐọc phiên bản sửa đổi hiện tại bằng GET trước. Phiên bản cũ sẽ thất bại mà không ghi đè chỉnh sửa của người khác.
settingsobjectbắt buộc
Giao diện thanh toán đã xác thực, gồm inherit_default_store, thương hiệu, lời mở/kết, cỡ chữ và hiển thị. Không có HTML/JavaScript tùy ý. Chỉ bảng điều khiển mới tải lên byte hình ảnh.Chi tiết
Giao diện thanh toán đã xác thực, gồm inherit_default_store, thương hiệu, lời mở/kết, cỡ chữ và hiển thị. Không có HTML/JavaScript tùy ý. Chỉ bảng điều khiển mới tải lên byte hình ảnh.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"settings": {
"inherit_default_store": false,
"title": "Pay securely",
"theme": "light"
},
"revision": 2
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê tài sản thanh toán của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
store_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": []
}Trường phản hồi
data[]arrayGhi chú sử dụng
- Cần projects.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTCập nhật tài sản thanh toán của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
store_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"assets": [
{
"asset_id": "11111111-1111-4111-8111-111111111111",
"display_order": 0
}
]
}'// 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 operation.
const body = `{
"assets": [
{
"asset_id": "11111111-1111-4111-8111-111111111111",
"display_order": 0
}
]
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"assets": [
{
"asset_id": "11111111-1111-4111-8111-111111111111",
"display_order": 0
}
]
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"assets": [
{
"asset_id": "11111111-1111-4111-8111-111111111111",
"display_order": 0
}
]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets",
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))Nội dung yêu cầu
assets[]object[]bắt buộc
Thay toàn bộ phương thức trên chuỗi: UUID asset_id và display_order. [] xóa tài sản trên chuỗi được chấp nhận. Chỉ tài sản dự án đã xác minh; không cấu hình Lightning.Chi tiết
Thay toàn bộ phương thức trên chuỗi: UUID asset_id và display_order. [] xóa tài sản trên chuỗi được chấp nhận. Chỉ tài sản dự án đã xác minh; không cấu hình Lightning.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": []
}Trường phản hồi
data[]arrayGhi chú sử dụng
- Cần projects.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê webhook của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
store_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTTạo webhook của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
store_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Orders",
"url": "https://shop.example.test/payments",
"event_types": [
"invoice.settled"
],
"enabled": true,
"automatic_redelivery": true
}'// 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 operation.
const body = `{
"name": "Orders",
"url": "https://shop.example.test/payments",
"event_types": [
"invoice.settled"
],
"enabled": true,
"automatic_redelivery": true
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"name": "Orders",
"url": "https://shop.example.test/payments",
"event_types": [
"invoice.settled"
],
"enabled": true,
"automatic_redelivery": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"name": "Orders",
"url": "https://shop.example.test/payments",
"event_types": [
"invoice.settled"
],
"enabled": true,
"automatic_redelivery": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks",
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))Nội dung yêu cầu
namestrings / arraybắt buộcBên nhận HTTPS công khai và tên sự kiện hóa đơn từ tài liệu IPN & webhook.
urlstrings / arraybắt buộcBên nhận HTTPS công khai và tên sự kiện hóa đơn từ tài liệu IPN & webhook.
event_types[]strings / arraybắt buộcBên nhận HTTPS công khai và tên sự kiện hóa đơn từ tài liệu IPN & webhook.
enabledbooleanstùy chọnTạo trả bí mật ký một lần. Đây là callback thanh toán cửa hàng, không phải sự kiện vòng đời Operator.
automatic_redeliverybooleanstùy chọnTạo trả bí mật ký một lần. Đây là callback thanh toán cửa hàng, không phải sự kiện vòng đời Operator.
Phản hồi 201 or 200 application/json
Phản hồi ví dụ
{
"signing_secret": "EXAMPLE_ONLY_SAVE_ONCE",
"endpoint": {
"id": "44444444-4444-4444-8444-444444444444",
"name": "Orders",
"enabled": true
},
"secret_visible_once": true
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTCập nhật webhook của cửa hàng/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooks/{webhook_id}Đọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
store_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
webhook_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks/YOUR_WEBHOOK_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Orders",
"url": "https://shop.example.test/payments",
"event_types": [
"invoice.settled"
],
"enabled": false,
"automatic_redelivery": true
}'// 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 operation.
const body = `{
"name": "Orders",
"url": "https://shop.example.test/payments",
"event_types": [
"invoice.settled"
],
"enabled": false,
"automatic_redelivery": true
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks/YOUR_WEBHOOK_ID", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"name": "Orders",
"url": "https://shop.example.test/payments",
"event_types": [
"invoice.settled"
],
"enabled": false,
"automatic_redelivery": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks/YOUR_WEBHOOK_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"name": "Orders",
"url": "https://shop.example.test/payments",
"event_types": [
"invoice.settled"
],
"enabled": false,
"automatic_redelivery": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/webhooks/YOUR_WEBHOOK_ID",
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))Nội dung yêu cầu
namestrings / arraybắt buộcBên nhận HTTPS công khai và tên sự kiện hóa đơn từ tài liệu IPN & webhook.
urlstrings / arraybắt buộcBên nhận HTTPS công khai và tên sự kiện hóa đơn từ tài liệu IPN & webhook.
event_types[]strings / arraybắt buộcBên nhận HTTPS công khai và tên sự kiện hóa đơn từ tài liệu IPN & webhook.
enabledbooleanstùy chọnTạo trả bí mật ký một lần. Đây là callback thanh toán cửa hàng, không phải sự kiện vòng đời Operator.
automatic_redeliverybooleanstùy chọnTạo trả bí mật ký một lần. Đây là callback thanh toán cửa hàng, không phải sự kiện vòng đời Operator.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"id": "44444444-4444-4444-8444-444444444444",
"name": "Orders",
"enabled": true
}Trường phản hồi
Ghi chú sử dụng
- Cần projects.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê hóa đơn/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoicesChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
Tham số truy vấn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"pagination": {
"limit": 25,
"offset": 0,
"total": 0,
"has_more": false
}
}Trường phản hồi
Ghi chú sử dụng
- Cần reports.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLấy hóa đơn/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoices/{invoice_id}Chỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
invoice_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices/YOUR_INVOICE_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices/YOUR_INVOICE_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices/YOUR_INVOICE_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/invoices/YOUR_INVOICE_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"invoice_id": "44444444-4444-4444-8444-444444444444",
"project_id": "33333333-3333-4333-8333-333333333333",
"amount": "25",
"currency": "EUR",
"status": "new",
"metadata": {},
"payment_intents": []
}Trường phản hồi
Ghi chú sử dụng
- Cần reports.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
- invoice_id là ID công khai của hóa đơn được trả khi tạo và trong callback, không phải id nội bộ.
Lỗi
GETLiệt kê ví/v1/operator/merchants/{merchant_id}/projects/{project_id}/walletsChỉ đọc
Đọc số dư ví công khai lưu đệm, không bao giờ đọc khóa riêng hay cụm từ khôi phục.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần reports.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Số dư là quan sát lưu đệm có trường độ mới, không bảo đảm số dư có thể chi tiêu. API này không cung cấp gửi tiền và xuất khóa.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê địa chỉ ví/v1/operator/merchants/{merchant_id}/projects/{project_id}/wallets/{wallet_id}/addressesChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
project_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
wallet_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Tham số truy vấn
limittùy chọnlimit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.Chi tiết
limit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.
beforetùy chọnlimit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.Chi tiết
limit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.
searchtùy chọnlimit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.Chi tiết
limit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.
has_balancetùy chọnlimit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.Chi tiết
limit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.
hide_small_balancestùy chọnlimit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.Chi tiết
limit 1–50, mặc định 25. Truyền next_cursor làm before cho trang tiếp theo. Bỏ before cho trang 1. has_balance=false và hide_small_balances=false bao gồm số dư rỗng/nhỏ.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets/YOUR_WALLET_ID/addresses" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets/YOUR_WALLET_ID/addresses", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets/YOUR_WALLET_ID/addresses");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/projects/YOUR_PROJECT_ID/wallets/YOUR_WALLET_ID/addresses",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"wallet": {
"id": "22222222-2222-4222-8222-222222222222",
"chain_slug": "ethereum"
},
"items": [],
"total": 0,
"total_pages": 1,
"next_cursor": null,
"reporting_currency": "EUR",
"has_balance": true,
"hide_small_balances": true,
"small_balance_threshold": {
"amount": "0.20",
"currency": "EUR"
}
}Trường phản hồi
Ghi chú sử dụng
- Cần reports.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETLiệt kê thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentialsChỉ đọc
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Tham số truy vấn
pagetùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
searchtùy chọnTrang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.Chi tiết
Trang bắt đầu từ 1, 25 mục mỗi trang. Hỗ trợ tìm kiếm trên nhà bán hàng, người dùng, dự án, cửa hàng, ví, thông tin xác thực và webhook; danh sách sự kiện gốc dùng bộ lọc riêng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Trường phản hồi
Ghi chú sử dụng
- Cần merchant_credentials.read; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTTạo thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentialsĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
merchant_idUUIDbắt buộcUUID tài nguyên chữ thường chính tắc; phải thuộc phạm vi nhà bán hàng của thông tin xác thực.
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Store integration",
"access_level": "read_only",
"enabled": true,
"ip_restriction_enabled": false,
"allowed_ips": [],
"project_ids": [
"11111111-1111-4111-8111-111111111111"
]
}'// 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 operation.
const body = `{
"name": "Store integration",
"access_level": "read_only",
"enabled": true,
"ip_restriction_enabled": false,
"allowed_ips": [],
"project_ids": [
"11111111-1111-4111-8111-111111111111"
]
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"name": "Store integration",
"access_level": "read_only",
"enabled": true,
"ip_restriction_enabled": false,
"allowed_ips": [],
"project_ids": [
"11111111-1111-4111-8111-111111111111"
]
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"name": "Store integration",
"access_level": "read_only",
"enabled": true,
"ip_restriction_enabled": false,
"allowed_ips": [],
"project_ids": [
"11111111-1111-4111-8111-111111111111"
]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials",
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))Nội dung yêu cầu
project_ids[]UUID[]Chỉ dự án thuộc nhà bán hàng được chọn; danh sách rỗng theo chính sách mọi dự án nhà bán hàng hiện có.
enabledtùy chọnCác điều khiển khóa nhà bán hàng hiện có. Bí mật chỉ trả một lần; cần merchant_credentials.write.
ip_restriction_enabledtùy chọnCác điều khiển khóa nhà bán hàng hiện có. Bí mật chỉ trả một lần; cần merchant_credentials.write.
allowed_ips[]tùy chọnCác điều khiển khóa nhà bán hàng hiện có. Bí mật chỉ trả một lần; cần merchant_credentials.write.
requests_per_minutetùy chọnCác điều khiển khóa nhà bán hàng hiện có. Bí mật chỉ trả một lần; cần merchant_credentials.write.
Phản hồi 201 or 200 application/json
Phản hồi ví dụ
{
"credential": {
"id": "22222222-2222-4222-8222-222222222222",
"name": "Checkout",
"access_level": "read_only",
"project_ids": [
"33333333-3333-4333-8333-333333333333"
],
"enabled": true
},
"token": "wc_live_EXAMPLE_ONLY_SAVE_ONCE"
}Trường phản hồi
Ghi chú sử dụng
- Cần merchant_credentials.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTCập nhật thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}Đọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Checkout",
"access_level": "read_only",
"enabled": true,
"ip_restriction_enabled": false,
"allowed_ips": [],
"project_ids": [
"33333333-3333-4333-8333-333333333333"
]
}'// 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 operation.
const body = `{
"name": "Checkout",
"access_level": "read_only",
"enabled": true,
"ip_restriction_enabled": false,
"allowed_ips": [],
"project_ids": [
"33333333-3333-4333-8333-333333333333"
]
}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{
"name": "Checkout",
"access_level": "read_only",
"enabled": true,
"ip_restriction_enabled": false,
"allowed_ips": [],
"project_ids": [
"33333333-3333-4333-8333-333333333333"
]
}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"name": "Checkout",
"access_level": "read_only",
"enabled": true,
"ip_restriction_enabled": false,
"allowed_ips": [],
"project_ids": [
"33333333-3333-4333-8333-333333333333"
]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID",
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))Nội dung yêu cầu
namefieldsbắt buộcGửi cấu hình thông tin xác thực hiện tại đầy đủ cùng thay đổi. project_ids mặc định []; requests_per_minute mặc định theo hạn mức API nhà bán hàng.
access_levelfieldsbắt buộcGửi cấu hình thông tin xác thực hiện tại đầy đủ cùng thay đổi. project_ids mặc định []; requests_per_minute mặc định theo hạn mức API nhà bán hàng.
enabledfieldsbắt buộcGửi cấu hình thông tin xác thực hiện tại đầy đủ cùng thay đổi. project_ids mặc định []; requests_per_minute mặc định theo hạn mức API nhà bán hàng.
ip_restriction_enabledfieldsbắt buộcGửi cấu hình thông tin xác thực hiện tại đầy đủ cùng thay đổi. project_ids mặc định []; requests_per_minute mặc định theo hạn mức API nhà bán hàng.
allowed_ips[]fieldsbắt buộcGửi cấu hình thông tin xác thực hiện tại đầy đủ cùng thay đổi. project_ids mặc định []; requests_per_minute mặc định theo hạn mức API nhà bán hàng.
project_ids[]arrayPhản hồi 200 application/json
Phản hồi ví dụ
{
"id": "22222222-2222-4222-8222-222222222222",
"name": "Checkout",
"access_level": "read_only",
"project_ids": [
"33333333-3333-4333-8333-333333333333"
],
"enabled": true
}Trường phản hồi
Ghi chú sử dụng
- Cần merchant_credentials.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTLuân chuyển thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/rotateĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/rotate" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{}'// 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 operation.
const body = `{}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/rotate", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/rotate");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/rotate",
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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"credential": {
"id": "22222222-2222-4222-8222-222222222222",
"name": "Checkout",
"access_level": "read_only",
"project_ids": [
"33333333-3333-4333-8333-333333333333"
],
"enabled": true
},
"token": "wc_live_EXAMPLE_ONLY_SAVE_ONCE"
}Trường phản hồi
Ghi chú sử dụng
- Cần merchant_credentials.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTThu hồi thông tin xác thực nhà bán hàng/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/revokeĐọc + ghi
Quản lý hoặc kiểm tra tài nguyên nhà bán hàng được lưu trữ đã chỉ định bằng thông tin xác thực Operator riêng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; được lưu bền vững cho thao tác này |
Tham số đường dẫn
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/revoke" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: operator-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{}'// 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 operation.
const body = `{}`;
const response = await fetch("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/revoke", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "operator-request-1042",
"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 operation.
$body = <<<'JSON'
{}
JSON;
$ch = curl_init("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/revoke");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: operator-request-1042", "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 operation.
headers = {
"Idempotency-Key": "operator-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{}""".encode("utf-8")
request = Request("https://api.example.com/v1/operator/merchants/YOUR_MERCHANT_ID/api-credentials/YOUR_CREDENTIAL_ID/revoke",
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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"revoked": true
}Trường phản hồi
revokedbooleanGhi chú sử dụng
- Cần merchant_credentials.write; chỉ các nhà bán hàng được lưu trữ được cho phép. Khóa Operator không truy cập không gian doanh nghiệp riêng của chủ sở hữu.
- Lưu bền vững Idempotency-Key duy nhất và nội dung chính xác trước khi gửi. Thử lại không bao giờ lặp thao tác đã ghi nhận. Trường bí mật được bỏ khi phát lại; nếu mất phản hồi bí mật, kiểm tra tài nguyên đã tạo rồi chủ động luân chuyển/cấp lại. 409 operator_request_in_progress có thể nghĩa là yêu cầu gián đoạn với kết quả chưa rõ: kiểm tra tài nguyên/kiểm toán; đừng mù quáng thử lại bằng khóa mới.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTKiểm tra token lời mời/v1/onboarding/invitations/checkCông khai
Tiếp nhận chỉ bằng token. Không chấp nhận khóa Operator hay tự đăng nhập. Đăng nhập bảng điều khiển vẫn cần Basic Auth của trang và TOTP hiện có.
Xác thực & header
Công khai
Yêu cầu
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/onboarding/invitations/check" \
--header 'Content-Type: application/json' \
--data-raw '{
"token": "YOUR_PRIVATE_INVITATION_TOKEN"
}'// Node.js 18+ · run on your server, never in browser code.
const body = `{
"token": "YOUR_PRIVATE_INVITATION_TOKEN"
}`;
const response = await fetch("https://api.example.com/v1/onboarding/invitations/check", {
method: "POST",
headers: {
"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.
$body = <<<'JSON'
{
"token": "YOUR_PRIVATE_INVITATION_TOKEN"
}
JSON;
$ch = curl_init("https://api.example.com/v1/onboarding/invitations/check");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["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
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {
"Content-Type": "application/json"
}
body = """{
"token": "YOUR_PRIVATE_INVITATION_TOKEN"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/onboarding/invitations/check",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"kind": "invitation",
"email": "admin@example.test",
"merchant_name": "Example shop"
}Trường phản hồi
Ghi chú sử dụng
- Lời mời 48 giờ; liên kết đặt lại mật khẩu một giờ. Token băm dùng một lần. Cấp lại thu hồi liên kết trước. Chấp nhận giữ TOTP và thu hồi phiên cũ.
- Không tự động thử lại. Nếu chấp nhận hết thời gian chờ, kiểm tra trạng thái liên kết và thử đăng nhập; đừng cho rằng nó đã thất bại. Giới hạn tần suất theo IP nguồn quan sát được. Người nhận phải tự xác nhận việc lưu ký.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
POSTChấp nhận lời mời hoặc đặt lại mật khẩu/v1/onboarding/invitations/acceptCông khai
Tiếp nhận chỉ bằng token. Không chấp nhận khóa Operator hay tự đăng nhập. Đăng nhập bảng điều khiển vẫn cần Basic Auth của trang và TOTP hiện có.
Xác thực & header
Công khai
Yêu cầu
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/onboarding/invitations/accept" \
--header 'Content-Type: application/json' \
--data-raw '{
"token": "YOUR_PRIVATE_INVITATION_TOKEN",
"password": "REPLACE_WITH_YOUR_OWN_UNIQUE_PASSWORD",
"custody_acknowledged": true
}'// Node.js 18+ · run on your server, never in browser code.
const body = `{
"token": "YOUR_PRIVATE_INVITATION_TOKEN",
"password": "REPLACE_WITH_YOUR_OWN_UNIQUE_PASSWORD",
"custody_acknowledged": true
}`;
const response = await fetch("https://api.example.com/v1/onboarding/invitations/accept", {
method: "POST",
headers: {
"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.
$body = <<<'JSON'
{
"token": "YOUR_PRIVATE_INVITATION_TOKEN",
"password": "REPLACE_WITH_YOUR_OWN_UNIQUE_PASSWORD",
"custody_acknowledged": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/onboarding/invitations/accept");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["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
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {
"Content-Type": "application/json"
}
body = """{
"token": "YOUR_PRIVATE_INVITATION_TOKEN",
"password": "REPLACE_WITH_YOUR_OWN_UNIQUE_PASSWORD",
"custody_acknowledged": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/onboarding/invitations/accept",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"password_set": true
}Trường phản hồi
password_setbooleanGhi chú sử dụng
- Lời mời 48 giờ; liên kết đặt lại mật khẩu một giờ. Token băm dùng một lần. Cấp lại thu hồi liên kết trước. Chấp nhận giữ TOTP và thu hồi phiên cũ.
- Không tự động thử lại. Nếu chấp nhận hết thời gian chờ, kiểm tra trạng thái liên kết và thử đăng nhập; đừng cho rằng nó đã thất bại. Giới hạn tần suất theo IP nguồn quan sát được. Người nhận phải tự xác nhận việc lưu ký.
- Ví dụ phản hồi hiển thị một số trường được chọn. Coi trường phản hồi bổ sung là phần mở rộng tương thích.
Lỗi
GETKhả năng/v1/marketplace/capabilitiesChỉ đọc
Cửa hàng tham gia, tài sản đã cấu hình, hệ thống chi trả được hỗ trợ, tài sản phí gốc và lý do trạng thái sẵn sàng. Tính khả dụng tạm thời của máy quét không mở rộng tập tài sản được phép.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/capabilities?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/capabilities?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/capabilities?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/capabilities?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETBáo cáo sàn thương mại/v1/marketplace/overviewChỉ đọc
Lọc store_id, asset_id, from và to (YYYY-MM-DD bao gồm hai đầu, UTC; mặc định 30 ngày qua; tối đa mười năm). Số dư tài khoản chính xác tại cuối ngày kết thúc và thay đổi trong kỳ. Không ước tính thu nhập tiền pháp định. Bộ lọc cửa hàng loại trừ phí toàn dự án không có hóa đơn.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/overview?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/overview?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/overview?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/overview?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETCài đặt dự án/v1/marketplace/settingsChỉ đọc
Trả enabled, payouts_paused, commission_percent, revision và các cửa hàng tham gia.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/settings?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/settings?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/settings?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/settings?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTLưu cài đặt dự án/v1/marketplace/settingsĐọc + ghi
Thay lựa chọn cửa hàng tham gia. revision 0 khởi tạo cài đặt; sửa về sau cần revision được trả về. Hoa hồng là tỷ lệ phần trăm thập phân, 0–100 với tối đa hai chữ số thập phân.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | policies.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/settings" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 0,
"enabled": true,
"payouts_paused": true,
"commission_percent": "4",
"stores": [
{
"store_id": "YOUR_STORE_ID",
"enabled": true,
"commission_percent": null
}
]
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 0,
"enabled": true,
"payouts_paused": true,
"commission_percent": "4",
"stores": [
{
"store_id": "YOUR_STORE_ID",
"enabled": true,
"commission_percent": null
}
]
}`;
const response = await fetch("https://api.example.com/v1/marketplace/settings", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 0,
"enabled": true,
"payouts_paused": true,
"commission_percent": "4",
"stores": [
{
"store_id": "YOUR_STORE_ID",
"enabled": true,
"commission_percent": null
}
]
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/settings");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 0,
"enabled": true,
"payouts_paused": true,
"commission_percent": "4",
"stores": [
{
"store_id": "YOUR_STORE_ID",
"enabled": true,
"commission_percent": null
}
]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/settings",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần policies.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETLiệt kê nhà bán hàng/v1/marketplace/vendorsChỉ đọc
Nhà bán hàng có phân trang. Tìm q theo tên, ID bên ngoài hoặc email; status là active, suspended hoặc archived.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/vendors?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/vendors?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/vendors?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/vendors?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTTạo nhà bán hàng/v1/marketplace/vendorsĐọc + ghi
Bắt buộc có tên (160 ký tự); external_id tùy chọn và duy nhất theo dự án (128); email tùy chọn (254); description tối đa 2000. commission_percent null kế thừa cửa hàng. Ghi đè khác null còn cần commissions.override. Nhà bán hàng trong sàn không phải tài khoản nhà bán hàng được lưu trữ.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | vendors.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/vendors" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"name": "Example vendor",
"external_id": "vendor-1042",
"email": "vendor@example.com",
"description": "",
"status": "active",
"commission_percent": null
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"name": "Example vendor",
"external_id": "vendor-1042",
"email": "vendor@example.com",
"description": "",
"status": "active",
"commission_percent": null
}`;
const response = await fetch("https://api.example.com/v1/marketplace/vendors", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"name": "Example vendor",
"external_id": "vendor-1042",
"email": "vendor@example.com",
"description": "",
"status": "active",
"commission_percent": null
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/vendors");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"name": "Example vendor",
"external_id": "vendor-1042",
"email": "vendor@example.com",
"description": "",
"status": "active",
"commission_percent": null
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/vendors",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần vendors.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETLấy nhà bán hàng/v1/marketplace/vendors/{vendor_id}Chỉ đọc
Trả một nhà bán hàng, phiên bản sửa đổi và ghi đè hoa hồng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTCập nhật nhà bán hàng/v1/marketplace/vendors/{vendor_id}/updateĐọc + ghi
Cập nhật chi tiết nhà bán hàng; status active hoặc suspended. Đổi hay bỏ commission_percent còn cần commissions.override; giá trị không đổi chỉ cần vendors.write. Khôi phục nhà bán hàng đã lưu trữ còn cần reconciliation.write. Chỉnh sửa tài chính trong bảng điều khiển cần xác thực lại tài khoản. Khoản phân bổ hiện có giữ hoa hồng và đích nhận ban đầu.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | vendors.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/update" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"name": "Example vendor",
"external_id": "vendor-1042",
"email": "vendor@example.com",
"description": "",
"status": "active",
"commission_percent": null,
"revision": 1
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"name": "Example vendor",
"external_id": "vendor-1042",
"email": "vendor@example.com",
"description": "",
"status": "active",
"commission_percent": null,
"revision": 1
}`;
const response = await fetch("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/update", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"name": "Example vendor",
"external_id": "vendor-1042",
"email": "vendor@example.com",
"description": "",
"status": "active",
"commission_percent": null,
"revision": 1
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/update");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"name": "Example vendor",
"external_id": "vendor-1042",
"email": "vendor@example.com",
"description": "",
"status": "active",
"commission_percent": null,
"revision": 1
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/update",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần vendors.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTLưu trữ nhà bán hàng/v1/marketplace/vendors/{vendor_id}/archiveĐọc + ghi
Chỉ lưu trữ sau khi giải quyết nghĩa vụ chưa trả và hóa đơn còn mở; nếu không trả 409 vendor_has_obligations. Lịch sử được giữ. Tạm dùng trạng thái suspended, hoặc khôi phục nhà bán hàng đã lưu trữ cũ bằng tuyến cập nhật và reconciliation.write.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | vendors.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/archive" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}`;
const response = await fetch("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/archive", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/archive");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/archive",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần vendors.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETĐích nhận của nhà bán hàng/v1/marketplace/vendors/{vendor_id}/destinationsChỉ đọc
Đích nhận có phiên bản và trạng thái pending/approved/disabled. Phê duyệt không chứng minh quyền sở hữu.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTThêm đích chi trả/v1/marketplace/vendors/{vendor_id}/destinationsĐọc + ghi
Đăng ký địa chỉ BTC mainnet hoặc EVM được hỗ trợ hợp lệ, chờ phê duyệt. Từ chối địa chỉ thuộc dự án, sai mạng và địa chỉ EVM bằng không.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | destinations.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"chain_slug": "bitcoin",
"network": "mainnet",
"address": "VERIFIED_VENDOR_BTC_ADDRESS",
"label": "Vendor BTC"
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"chain_slug": "bitcoin",
"network": "mainnet",
"address": "VERIFIED_VENDOR_BTC_ADDRESS",
"label": "Vendor BTC"
}`;
const response = await fetch("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"chain_slug": "bitcoin",
"network": "mainnet",
"address": "VERIFIED_VENDOR_BTC_ADDRESS",
"label": "Vendor BTC"
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"chain_slug": "bitcoin",
"network": "mainnet",
"address": "VERIFIED_VENDOR_BTC_ADDRESS",
"label": "Vendor BTC"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần destinations.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTPhê duyệt đích nhận/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/approveĐọc + ghi
Xác minh quyền sở hữu độc lập trước. Trước hết tắt đích nhận đã phê duyệt hiện có của nhà bán hàng/mạng này; bản chụp cũ không được chuyển hướng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | destinations.approve |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/approve" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}`;
const response = await fetch("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/approve", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/approve");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/approve",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần destinations.approve. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTVô hiệu hóa đích nhận/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/disableĐọc + ghi
Dừng công việc mới/chưa gửi dùng phiên bản này. Không thể thu hồi giao dịch đã ký.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | destinations.approve |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/disable" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}`;
const response = await fetch("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/disable", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/disable");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/destinations/YOUR_DESTINATION_ID/disable",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần destinations.approve. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETSố dư nhà bán hàng/v1/marketplace/vendors/{vendor_id}/balancesChỉ đọc
Số tiền sổ cái được lưu chính xác, nhóm theo danh tính tài sản bất biến và loại tài khoản; không phải số dư ví có thể chi tiêu trực tiếp.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/balances?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/balances?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/balances?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/vendors/YOUR_VENDOR_ID/balances?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETHóa đơn sàn thương mại/v1/marketplace/invoicesChỉ đọc
Hóa đơn có phân trang; q tìm theo đơn hàng, email, mô tả, metadata và UUID hóa đơn. Lọc store_id, vendor_id và trạng thái Marketplace. Loại trừ hóa đơn thông thường.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/invoices?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/invoices?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/invoices?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/invoices?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTTạo hóa đơn nhiều nhà bán hàng/v1/marketplace/invoicesĐọc + ghi
Dùng lại trường InvoiceCreateInput thông thường, cộng store_id và allocations. Mỗi nhà bán hàng xuất hiện một lần, 1–100 phần dương, tổng bằng chính xác amount. commission_percent tùy chọn của hóa đơn/từng khoản phân bổ cần commissions.override và xác thực lại trong bảng điều khiển với yêu cầu từ phiên. Trả data.invoice_id và links.checkout. Không có phương thức chung tương thích sẽ trả lỗi chi tiết; không chuyển sang tài sản không tương thích.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | invoices.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/invoices" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"store_id": "YOUR_STORE_ID",
"amount": "300.00",
"currency": "USD",
"order_id": "cart-1042",
"allocations": [
{
"vendor_id": "VENDOR_A_UUID",
"gross_amount": "100.00"
},
{
"vendor_id": "VENDOR_B_UUID",
"gross_amount": "100.00"
},
{
"vendor_id": "VENDOR_C_UUID",
"gross_amount": "100.00"
}
]
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"store_id": "YOUR_STORE_ID",
"amount": "300.00",
"currency": "USD",
"order_id": "cart-1042",
"allocations": [
{
"vendor_id": "VENDOR_A_UUID",
"gross_amount": "100.00"
},
{
"vendor_id": "VENDOR_B_UUID",
"gross_amount": "100.00"
},
{
"vendor_id": "VENDOR_C_UUID",
"gross_amount": "100.00"
}
]
}`;
const response = await fetch("https://api.example.com/v1/marketplace/invoices", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"store_id": "YOUR_STORE_ID",
"amount": "300.00",
"currency": "USD",
"order_id": "cart-1042",
"allocations": [
{
"vendor_id": "VENDOR_A_UUID",
"gross_amount": "100.00"
},
{
"vendor_id": "VENDOR_B_UUID",
"gross_amount": "100.00"
},
{
"vendor_id": "VENDOR_C_UUID",
"gross_amount": "100.00"
}
]
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/invoices");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"store_id": "YOUR_STORE_ID",
"amount": "300.00",
"currency": "USD",
"order_id": "cart-1042",
"allocations": [
{
"vendor_id": "VENDOR_A_UUID",
"gross_amount": "100.00"
},
{
"vendor_id": "VENDOR_B_UUID",
"gross_amount": "100.00"
},
{
"vendor_id": "VENDOR_C_UUID",
"gross_amount": "100.00"
}
]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/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))Nội dung yêu cầu
amountstringbắt buộcChuỗi thập phân thuần không dấu; không dấu hay số mũ, tối đa 48 chữ số nguyên và 30 chữ số thập phân. Mặc định phải dương. Cửa hàng có thể cho phép hóa đơn số tiền bằng không trong Cửa hàng → Hóa đơn; tổng bằng không được quyết toán mà không nhận tiền, cấp địa chỉ hay tính phí xử lý.Chi tiết
Chuỗi thập phân thuần không dấu; không dấu hay số mũ, tối đa 48 chữ số nguyên và 30 chữ số thập phân. Mặc định phải dương. Cửa hàng có thể cho phép hóa đơn số tiền bằng không trong Cửa hàng → Hóa đơn; tổng bằng không được quyết toán mà không nhận tiền, cấp địa chỉ hay tính phí xử lý.
currencystring | nulltùy chọnTiền pháp định ba chữ cái được hỗ trợ, chuẩn hóa thành chữ hoa. Bỏ qua hoặc null kế thừa tiền hóa đơn của cửa hàng. Tạo hóa đơn cũng cần tỷ giá quy đổi tính phí độc lập có sẵn.Chi tiết
Tiền pháp định ba chữ cái được hỗ trợ, chuẩn hóa thành chữ hoa. Bỏ qua hoặc null kế thừa tiền hóa đơn của cửa hàng. Tạo hóa đơn cũng cần tỷ giá quy đổi tính phí độc lập có sẵn.
payment_methods[]object[] | nulltùy chọn
Chọn phương thức đang bật của cửa hàng cho hóa đơn này. Merchant 5.4.0+: bỏ qua lựa chọn không xác định/không hoạt động/không được chấp nhận; nếu không khớp lựa chọn nào, dùng mặc định cửa hàng. Bỏ qua/null cũng dùng mặc định cửa hàng; [] không hợp lệ. Không bao giờ bật phương thức hay đổi cài đặt cửa hàng. Xem lược đồ lựa chọn bên dưới.Chi tiết
Chọn phương thức đang bật của cửa hàng cho hóa đơn này. Merchant 5.4.0+: bỏ qua lựa chọn không xác định/không hoạt động/không được chấp nhận; nếu không khớp lựa chọn nào, dùng mặc định cửa hàng. Bỏ qua/null cũng dùng mặc định cửa hàng; [] không hợp lệ. Không bao giờ bật phương thức hay đổi cài đặt cửa hàng. Xem lược đồ lựa chọn bên dưới.
chain_slugstringbắt buộcSao chép chain_slug trong Dự án → Cửa hàng → Phương thức thanh toán, hoặc đọc từ GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, như ethereum, base hoặc bitcoin. Mỗi cặp chuỗi/hệ thống thanh toán chỉ được xuất hiện một lần.Chi tiết
Sao chép chain_slug trong Dự án → Cửa hàng → Phương thức thanh toán, hoặc đọc từ GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, như ethereum, base hoặc bitcoin. Mỗi cặp chuỗi/hệ thống thanh toán chỉ được xuất hiện một lần.
asset_ids[]UUID[] | nulltùy chọnUUID asset.id trên chuỗi, không phải địa chỉ hợp đồng hay ID phương thức thanh toán hóa đơn. Dùng trường này HOẶC asset_tickers. Bỏ cả hai bộ chọn để lấy mọi tài sản đang hoạt động được chấp nhận trên chuỗi này. [] và ID trùng/rỗng không hợp lệ. Trên 5.4.0+, bỏ qua ID không hoạt động/không được chấp nhận trên chuỗi này trong cửa hàng này; lựa chọn hoàn toàn không khớp sẽ dùng mặc định cửa hàng.Chi tiết
UUID asset.id trên chuỗi, không phải địa chỉ hợp đồng hay ID phương thức thanh toán hóa đơn. Dùng trường này HOẶC asset_tickers. Bỏ cả hai bộ chọn để lấy mọi tài sản đang hoạt động được chấp nhận trên chuỗi này. [] và ID trùng/rỗng không hợp lệ. Trên 5.4.0+, bỏ qua ID không hoạt động/không được chấp nhận trên chuỗi này trong cửa hàng này; lựa chọn hoàn toàn không khớp sẽ dùng mặc định cửa hàng.
asset_tickers[]string[] | nulltùy chọnMerchant 5.3.0+. Ký hiệu như BTC, USDC hoặc PEPE, giới hạn theo chain_slug và cửa hàng này. 1–64 mã duy nhất; bỏ khoảng trắng hai đầu/không phân biệt hoa thường, 1–40 chữ ASCII/số/dấu chấm/gạch dưới/gạch nối. Dùng trường này HOẶC asset_ids. Trên 5.4.0+, bỏ qua mã không xác định/không hoạt động/không được chấp nhận. Ký hiệu được chấp nhận nhưng mơ hồ vẫn gây lỗi: dùng asset_ids. Phương thức đang hoạt động được chọn cần ví và định giá hợp lệ; sự cố máy quét trên chuỗi tạm thời không chặn tạo hóa đơn từ 6.0.6. Lightning tùy chọn chỉ chấp nhận BTC.Chi tiết
Merchant 5.3.0+. Ký hiệu như BTC, USDC hoặc PEPE, giới hạn theo chain_slug và cửa hàng này. 1–64 mã duy nhất; bỏ khoảng trắng hai đầu/không phân biệt hoa thường, 1–40 chữ ASCII/số/dấu chấm/gạch dưới/gạch nối. Dùng trường này HOẶC asset_ids. Trên 5.4.0+, bỏ qua mã không xác định/không hoạt động/không được chấp nhận. Ký hiệu được chấp nhận nhưng mơ hồ vẫn gây lỗi: dùng asset_ids. Phương thức đang hoạt động được chọn cần ví và định giá hợp lệ; sự cố máy quét trên chuỗi tạm thời không chặn tạo hóa đơn từ 6.0.6. Lightning tùy chọn chỉ chấp nhận BTC.
payment_railonchain | lightningtùy chọnMặc định onchain. Để chọn Bitcoin Lightning, dùng {chain_slug: bitcoin, payment_rail: lightning} không có asset_ids; asset_tickers có thể tùy chọn là [BTC]. Bitcoin trên chuỗi không bao gồm Lightning. Kết nối Lightning của cửa hàng phải được bật và sẵn sàng từ trước.Chi tiết
Mặc định onchain. Để chọn Bitcoin Lightning, dùng {chain_slug: bitcoin, payment_rail: lightning} không có asset_ids; asset_tickers có thể tùy chọn là [BTC]. Bitcoin trên chuỗi không bao gồm Lightning. Kết nối Lightning của cửa hàng phải được bật và sẵn sàng từ trước.
order_idstring | nulltùy chọnMã tham chiếu đơn hàng của nhà bán hàng, 1–128 ký tự sau khi bỏ khoảng trắng hai đầu; từ chối ký tự điều khiển.
emailstring | nulltùy chọnEmail khách hàng chỉ dành cho nhà bán hàng, chuẩn hóa thành địa chỉ ASCII thực tế tối đa 254 ký tự. Bỏ qua hoặc null sẽ không lưu email.
descriptionstring | nulltùy chọnMô tả hiển thị cho khách hàng, 1–500 ký tự; cho phép xuống dòng và tab.
expires_in_secondsinteger | nulltùy chọnThời hạn báo giá hóa đơn từ 300 đến 86,400 giây; bỏ qua hoặc null kế thừa chính sách cửa hàng.
exchange_rate_spread_percentdecimal string | nulltùy chọnPhần cộng giá từ 0 đến 100, tối đa hai chữ số thập phân. Bỏ qua hoặc null kế thừa mặc định cửa hàng; "0" tắt cho hóa đơn này. Áp dụng trước làm tròn lên, rồi khóa lại. Không đổi số tiền pháp định hóa đơn hay cơ sở phí xử lý.Chi tiết
Phần cộng giá từ 0 đến 100, tối đa hai chữ số thập phân. Bỏ qua hoặc null kế thừa mặc định cửa hàng; "0" tắt cho hóa đơn này. Áp dụng trước làm tròn lên, rồi khóa lại. Không đổi số tiền pháp định hóa đơn hay cơ sở phí xử lý.
underpayment_tolerance_percentdecimal string | nulltùy chọnPhần thiếu được chấp nhận từ 0 đến 99.99, tối đa hai chữ số thập phân. Bỏ qua hoặc null kế thừa mặc định cửa hàng.
ipn_urlstring | nulltùy chọnCallback HTTPS công khai, tối đa 2,048 byte, không có thông tin xác thực hay fragment. Ghi đè mặc định cửa hàng; null/bỏ qua kế thừa nó.
redirect_urlstring | nulltùy chọnURL thành công HTTPS dùng sau quyết toán, tối đa 2,048 byte, không nhúng thông tin xác thực. Bỏ qua hoặc null kế thừa mặc định cửa hàng và không thể xóa nó.
cancel_urlstring | nulltùy chọnURL trả về HTTPS dùng khi thanh toán kết thúc mà chưa thành công. Bỏ qua hoặc null kế thừa mặc định cửa hàng và không thể xóa nó.
redirect_automaticallyboolean | nulltùy chọnBỏ qua hoặc null kế thừa chính sách cửa hàng. true cần redirect_url có hiệu lực.
languagestring | nulltùy chọnNgôn ngữ khách hàng: en, de, es, pt-BR, it, ru, zh-CN, fr, ko hoặc ja. pt nghĩa là tiếng Bồ Đào Nha Brazil và zh nghĩa là tiếng Trung giản thể. Thẻ khu vực được hỗ trợ như de-DE được chuẩn hóa về ngôn ngữ trong danh sách. Bỏ qua hoặc null kế thừa ngôn ngữ cửa hàng. Ngôn ngữ bảng điều khiển tách biệt.Chi tiết
Ngôn ngữ khách hàng: en, de, es, pt-BR, it, ru, zh-CN, fr, ko hoặc ja. pt nghĩa là tiếng Bồ Đào Nha Brazil và zh nghĩa là tiếng Trung giản thể. Thẻ khu vực được hỗ trợ như de-DE được chuẩn hóa về ngôn ngữ trong danh sách. Bỏ qua hoặc null kế thừa ngôn ngữ cửa hàng. Ngôn ngữ bảng điều khiển tách biệt.
checkout_appearanceobject | nulltùy chọn
Cài đặt trình bày một phần cho hóa đơn này. Bỏ qua/null theo thiết kế hiện tại của cửa hàng. Một đối tượng, kể cả {}, đóng băng thiết kế đã phân giải và hình ảnh lúc tạo. Xem lược đồ ghi đè bên dưới; không có cài đặt tài chính, HTML, CSS, JavaScript hay URL ảnh từ xa.Chi tiết
Cài đặt trình bày một phần cho hóa đơn này. Bỏ qua/null theo thiết kế hiện tại của cửa hàng. Một đối tượng, kể cả {}, đóng băng thiết kế đã phân giải và hình ảnh lúc tạo. Xem lược đồ ghi đè bên dưới; không có cài đặt tài chính, HTML, CSS, JavaScript hay URL ảnh từ xa.
inherit_default_storebooleantùy chọntrue chọn thiết kế cửa hàng mặc định của dự án làm nền; nếu không dùng thiết kế có hiệu lực của cửa hàng đích. Sau đó áp dụng và lưu ghi đè độc lập; cờ hóa đơn sau phân giải là false.Chi tiết
true chọn thiết kế cửa hàng mặc định của dự án làm nền; nếu không dùng thiết kế có hiệu lực của cửa hàng đích. Sau đó áp dụng và lưu ghi đè độc lập; cờ hóa đơn sau phân giải là false.
introstringtùy chọnVăn bản thuần, mỗi mục tối đa 2,000 ký tự. Lời mở ở trên, lời kết ở dưới trong mọi trạng thái. Giữ xuống dòng; URL văn bản an toàn trở thành liên kết. Chuỗi rỗng sẽ xóa. customer_message cũ được chấp nhận làm bí danh cho intro; không gửi cả hai.Chi tiết
Văn bản thuần, mỗi mục tối đa 2,000 ký tự. Lời mở ở trên, lời kết ở dưới trong mọi trạng thái. Giữ xuống dòng; URL văn bản an toàn trở thành liên kết. Chuỗi rỗng sẽ xóa. customer_message cũ được chấp nhận làm bí danh cho intro; không gửi cả hai.
outrostringtùy chọnVăn bản thuần, mỗi mục tối đa 2,000 ký tự. Lời mở ở trên, lời kết ở dưới trong mọi trạng thái. Giữ xuống dòng; URL văn bản an toàn trở thành liên kết. Chuỗi rỗng sẽ xóa. customer_message cũ được chấp nhận làm bí danh cho intro; không gửi cả hai.Chi tiết
Văn bản thuần, mỗi mục tối đa 2,000 ký tự. Lời mở ở trên, lời kết ở dưới trong mọi trạng thái. Giữ xuống dòng; URL văn bản an toàn trở thành liên kết. Chuỗi rỗng sẽ xóa. customer_message cũ được chấp nhận làm bí danh cho intro; không gửi cả hai.
intro_font_sizeintegertùy chọnPixel: 12, 14, 16, 18, 20 hoặc 24. Mặc định 16 nếu không kế thừa giá trị khác.
outro_font_sizeintegertùy chọnPixel: 12, 14, 16, 18, 20 hoặc 24. Mặc định 16 nếu không kế thừa giá trị khác.
accent_colorstringtùy chọn#RRGGBB. Nền, thẻ và nút có thể rỗng để dùng màu tự động. Tương phản chữ tự động.
background_colorstringtùy chọn#RRGGBB. Nền, thẻ và nút có thể rỗng để dùng màu tự động. Tương phản chữ tự động.
card_colorstringtùy chọn#RRGGBB. Nền, thẻ và nút có thể rỗng để dùng màu tự động. Tương phản chữ tự động.
button_colorstringtùy chọn#RRGGBB. Nền, thẻ và nút có thể rỗng để dùng màu tự động. Tương phản chữ tự động.
imagesobjecttùy chọn
Các khóa logo_light, logo_dark, favicon. Bỏ khóa giữ ảnh nền; null xóa ảnh. Đối tượng {store_id: UUID, kind?: logo_light|logo_dark|favicon} dùng lại ảnh tải lên có hiệu lực của cửa hàng đó trong CÙNG dự án. kind mặc định theo khóa đích. Tải lên tại Cửa hàng → Trang thanh toán trước; sao chép ID API cửa hàng từ Cơ bản → ID API. Thiếu ảnh hoặc ID khác dự án trả 400. Không chấp nhận URL ngoài hay dữ liệu ảnh.Chi tiết
Các khóa logo_light, logo_dark, favicon. Bỏ khóa giữ ảnh nền; null xóa ảnh. Đối tượng {store_id: UUID, kind?: logo_light|logo_dark|favicon} dùng lại ảnh tải lên có hiệu lực của cửa hàng đó trong CÙNG dự án. kind mặc định theo khóa đích. Tải lên tại Cửa hàng → Trang thanh toán trước; sao chép ID API cửa hàng từ Cơ bản → ID API. Thiếu ảnh hoặc ID khác dự án trả 400. Không chấp nhận URL ngoài hay dữ liệu ảnh.
show_order_idbooleantùy chọnHiển thị chi tiết ID đơn hàng và mô tả văn bản thuần dưới tiêu đề. details_expanded mở sẵn chi tiết ID đơn hàng. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
show_descriptionbooleantùy chọnHiển thị chi tiết ID đơn hàng và mô tả văn bản thuần dưới tiêu đề. details_expanded mở sẵn chi tiết ID đơn hàng. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
details_expandedbooleantùy chọnHiển thị chi tiết ID đơn hàng và mô tả văn bản thuần dưới tiêu đề. details_expanded mở sẵn chi tiết ID đơn hàng. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
show_project_namebooleantùy chọnMerchant 5.6.0+: hiện hoặc ẩn từng tên trong phần đầu trang thanh toán khách hàng. Cả hai mặc định true. Cũng có tại Cửa hàng → Trang thanh toán; được kế thừa và chụp lưu theo hóa đơn như cài đặt giao diện khác. Chỉ ảnh hưởng hiển thị, không che dữ liệu.Chi tiết
Merchant 5.6.0+: hiện hoặc ẩn từng tên trong phần đầu trang thanh toán khách hàng. Cả hai mặc định true. Cũng có tại Cửa hàng → Trang thanh toán; được kế thừa và chụp lưu theo hóa đơn như cài đặt giao diện khác. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
show_store_namebooleantùy chọnMerchant 5.6.0+: hiện hoặc ẩn từng tên trong phần đầu trang thanh toán khách hàng. Cả hai mặc định true. Cũng có tại Cửa hàng → Trang thanh toán; được kế thừa và chụp lưu theo hóa đơn như cài đặt giao diện khác. Chỉ ảnh hưởng hiển thị, không che dữ liệu.Chi tiết
Merchant 5.6.0+: hiện hoặc ẩn từng tên trong phần đầu trang thanh toán khách hàng. Cả hai mặc định true. Cũng có tại Cửa hàng → Trang thanh toán; được kế thừa và chụp lưu theo hóa đơn như cài đặt giao diện khác. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
featured_chains[]string[]tùy chọnSlug chuỗi có thứ tự, tối đa 60 giá trị duy nhất (chữ thường, số, gạch nối; tối đa 64 ký tự). [] xóa. Chỉ phương thức hóa đơn khả dụng được sắp lại.Chi tiết
Slug chuỗi có thứ tự, tối đa 60 giá trị duy nhất (chữ thường, số, gạch nối; tối đa 64 ký tự). [] xóa. Chỉ phương thức hóa đơn khả dụng được sắp lại.
featured_asset_ids[]UUID[]tùy chọnTối đa 100 ID tài sản duy nhất có thứ tự; [] xóa. Tài sản mặc định có thể null. ID lấy từ payment-assets, không phải ID ý định thanh toán. Chúng không bao giờ bật phương thức; thanh toán đã nhận và tùy chọn khách hàng hợp lệ được ưu tiên.Chi tiết
Tối đa 100 ID tài sản duy nhất có thứ tự; [] xóa. Tài sản mặc định có thể null. ID lấy từ payment-assets, không phải ID ý định thanh toán. Chúng không bao giờ bật phương thức; thanh toán đã nhận và tùy chọn khách hàng hợp lệ được ưu tiên.
default_asset_idUUID|nulltùy chọnTối đa 100 ID tài sản duy nhất có thứ tự; [] xóa. Tài sản mặc định có thể null. ID lấy từ payment-assets, không phải ID ý định thanh toán. Chúng không bao giờ bật phương thức; thanh toán đã nhận và tùy chọn khách hàng hợp lệ được ưu tiên.Chi tiết
Tối đa 100 ID tài sản duy nhất có thứ tự; [] xóa. Tài sản mặc định có thể null. ID lấy từ payment-assets, không phải ID ý định thanh toán. Chúng không bao giờ bật phương thức; thanh toán đã nhận và tùy chọn khách hàng hợp lệ được ưu tiên.
messagesobjecttùy chọn
Đối tượng ngôn ngữ có khóa en, de, es, pt-BR, it, ru, zh-CN, fr, ko hoặc ja, với chuỗi thuần waiting, confirming, paid, underpaid, expired (mỗi chuỗi 500 ký tự). Chỉ ngôn ngữ/trạng thái được cung cấp thay đổi; {} xóa mọi thông báo, {en:{}} xóa tiếng Anh và chuỗi trạng thái rỗng xóa trạng thái đó. Tiếng Anh là dự phòng. Không thay trạng thái thực tế.Chi tiết
Đối tượng ngôn ngữ có khóa en, de, es, pt-BR, it, ru, zh-CN, fr, ko hoặc ja, với chuỗi thuần waiting, confirming, paid, underpaid, expired (mỗi chuỗi 500 ký tự). Chỉ ngôn ngữ/trạng thái được cung cấp thay đổi; {} xóa mọi thông báo, {en:{}} xóa tiếng Anh và chuỗi trạng thái rỗng xóa trạng thái đó. Tiếng Anh là dự phòng. Không thay trạng thái thực tế.
enobjecttùy chọn
deobjecttùy chọn
esobjecttùy chọn
pt-BRobjecttùy chọn
itobjecttùy chọn
ruobjecttùy chọn
zh-CNobjecttùy chọn
frobjecttùy chọn
koobjecttùy chọn
support_urlstringtùy chọnURL HTTPS tối đa 2,048 ký tự, không có thông tin xác thực. Rỗng sẽ xóa. Liên kết mở trong cửa sổ mới.
terms_urlstringtùy chọnURL HTTPS tối đa 2,048 ký tự, không có thông tin xác thực. Rỗng sẽ xóa. Liên kết mở trong cửa sổ mới.
privacy_urlstringtùy chọnURL HTTPS tối đa 2,048 ký tự, không có thông tin xác thực. Rỗng sẽ xóa. Liên kết mở trong cửa sổ mới.
return_button_textstringtùy chọnNhãn tối đa 60 ký tự. Dùng redirect_url/cancel_url/redirect_automatically/language cấp cao nhất cho hành vi hóa đơn.
show_return_buttonbooleantùy chọnHiển thị nút thủ công Quay lại nhà bán hàng/hủy trên trang thanh toán, kể cả trạng thái kết thúc. Bỏ qua để kế thừa giao diện cửa hàng (mặc định true); false ẩn nút. Không hủy hóa đơn, ẩn URL trong JSON hay tắt chuyển hướng thành công tự động. Đặt riêng redirect_automatically cấp cao nhất thành false nếu cần. Yêu cầu merchant 8.1.4 hoặc mới hơn.Chi tiết
Hiển thị nút thủ công Quay lại nhà bán hàng/hủy trên trang thanh toán, kể cả trạng thái kết thúc. Bỏ qua để kế thừa giao diện cửa hàng (mặc định true); false ẩn nút. Không hủy hóa đơn, ẩn URL trong JSON hay tắt chuyển hướng thành công tự động. Đặt riêng redirect_automatically cấp cao nhất thành false nếu cần. Yêu cầu merchant 8.1.4 hoặc mới hơn.
metadataobject | nulltùy chọn
Đối tượng JSON chỉ dành cho nhà bán hàng; bỏ qua hoặc null trở thành {}, tối đa 4,096 byte mã hóa và năm cấp lồng nhau. firstname, lastname, street, street2, zip, city, country, countryiso2, company và vatid được xác thực, chuẩn hóa và đưa vào trường tóm tắt khách hàng.Chi tiết
Đối tượng JSON chỉ dành cho nhà bán hàng; bỏ qua hoặc null trở thành {}, tối đa 4,096 byte mã hóa và năm cấp lồng nhau. firstname, lastname, street, street2, zip, city, country, countryiso2, company và vatid được xác thực, chuẩn hóa và đưa vào trường tóm tắt khách hàng.
allocations[]object[]
[{"vendor_id":"VENDOR_A_UUID","gross_amount":"100.00"},{"vendor_id":"VENDOR_B_UUID","gross_amount":"100.00"},{"vendor_id":"VENDOR_C_UUID","gross_amount":"100.00"}]Chi tiết
[{"vendor_id":"VENDOR_A_UUID","gross_amount":"100.00"},{"vendor_id":"VENDOR_B_UUID","gross_amount":"100.00"},{"vendor_id":"VENDOR_C_UUID","gross_amount":"100.00"}]
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {
"invoice_id": "YOUR_INVOICE_ID",
"status": "new",
"marketplace": {
"state": "pending",
"allocations": []
}
},
"links": {
"checkout": "https://pay.example.com/invoice/YOUR_INVOICE_ID"
}
}Trường phản hồi
Ghi chú sử dụng
- Cần invoices.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETHóa đơn và khoản phân bổ/v1/marketplace/invoices/{invoice_id}Chỉ đọc
Chi tiết hóa đơn thông thường cộng trạng thái marketplace, revision, hold_reason, khoản phân bổ đóng băng, bản chụp chính sách, 200 khoản thanh toán mới nhất và 100 khoản chi trả liên quan mới nhất kèm cờ cắt bớt. Trang thanh toán công khai không cung cấp dữ liệu nhà bán hàng trong sàn.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETBằng chứng thanh toán hóa đơn/v1/marketplace/invoices/{invoice_id}/paymentsChỉ đọc
Bằng chứng thanh toán thông thường với page/per_page. Quan sát không phải chi trả cho nhà bán hàng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/payments?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/payments?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/payments?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/payments?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETKhoản phân bổ hóa đơn/v1/marketplace/invoices/{invoice_id}/allocationsChỉ đọc
Bản chụp phần chia/hoa hồng/đích nhận bất biến và giá trị tổng, hoa hồng, ròng chính xác theo đơn vị nhỏ nhất sau quyết toán đủ điều kiện.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTHủy hóa đơn chưa thanh toán/v1/marketplace/invoices/{invoice_id}/cancelĐọc + ghi
Chỉ hóa đơn new hoặc expired chưa thanh toán. Khoản nhận muộn được giữ để xem xét. Revision là phiên bản sửa đổi hóa đơn Marketplace.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | invoices.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/cancel" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}`;
const response = await fetch("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/cancel", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/cancel");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/cancel",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần invoices.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTGiữ khoản phân bổ/v1/marketplace/invoices/{invoice_id}/allocations/holdĐọc + ghi
Giữ khoản phân bổ chưa ký mà không xóa nghĩa vụ. Chi trả đã ký hoặc chưa chắc chắn vẫn được theo dõi.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | reconciliation.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/hold" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"reason": "Verify customer request"
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"reason": "Verify customer request"
}`;
const response = await fetch("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/hold", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"reason": "Verify customer request"
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/hold");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"reason": "Verify customer request"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/hold",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần reconciliation.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTXem xét và giải phóng khoản phân bổ/v1/marketplace/invoices/{invoice_id}/allocations/releaseĐọc + ghi
Kiểm tra lại bảo chứng/tính hoàn tất. approved_amount_atomic tùy chọn chấp nhận rõ phần chia giảm được bảo chứng đầy đủ trước khi đóng băng khoản phân bổ; không bao giờ tạo tiền nhận giả.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | reconciliation.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/release" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"reason": "Verified payment evidence"
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"reason": "Verified payment evidence"
}`;
const response = await fetch("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/release", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"reason": "Verified payment evidence"
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/release");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"reason": "Verified payment evidence"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/release",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần reconciliation.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTGán lại đích nhận chưa thanh toán/v1/marketplace/invoices/{invoice_id}/allocations/{allocation_id}/destinationĐọc + ghi
Cần phiên bản sửa đổi khoản phân bổ. Chỉ công việc chưa giữ chỗ/chưa ký và phiên bản được phê duyệt riêng cho cùng nhà bán hàng trên mạng gốc. Có kiểm toán; công việc đã ký không thể đổi.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | reconciliation.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/YOUR_ALLOCATION_ID/destination" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"destination_id": "YOUR_DESTINATION_ID",
"reason": "Vendor verified replacement address"
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"destination_id": "YOUR_DESTINATION_ID",
"reason": "Vendor verified replacement address"
}`;
const response = await fetch("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/YOUR_ALLOCATION_ID/destination", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"destination_id": "YOUR_DESTINATION_ID",
"reason": "Vendor verified replacement address"
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/YOUR_ALLOCATION_ID/destination");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"destination_id": "YOUR_DESTINATION_ID",
"reason": "Vendor verified replacement address"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/allocations/YOUR_ALLOCATION_ID/destination",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần reconciliation.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTChuẩn bị hoàn tiền toàn bộ/v1/marketplace/invoices/{invoice_id}/refundĐọc + ghi
Chuẩn bị hoàn toàn bộ số tiền đã nhận bằng cùng tài sản, được phê duyệt riêng. Trước chi trả nhà bán hàng, giữ chỗ tiền chưa trả và đảo hoa hồng khi xác nhận. Sau mọi chi trả nhà bán hàng, dùng tiền tự do riêng tại địa chỉ chính. Không bao giờ suy ra địa chỉ hoàn tiền khách hàng từ người gửi.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | reconciliation.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/refund" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"payment_method_id": "YOUR_PAYMENT_METHOD_ID",
"destination_address": "VERIFIED_CUSTOMER_REFUND_ADDRESS",
"reason": "Customer cancellation",
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"payment_method_id": "YOUR_PAYMENT_METHOD_ID",
"destination_address": "VERIFIED_CUSTOMER_REFUND_ADDRESS",
"reason": "Customer cancellation",
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}`;
const response = await fetch("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/refund", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"payment_method_id": "YOUR_PAYMENT_METHOD_ID",
"destination_address": "VERIFIED_CUSTOMER_REFUND_ADDRESS",
"reason": "Customer cancellation",
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/refund");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"payment_method_id": "YOUR_PAYMENT_METHOD_ID",
"destination_address": "VERIFIED_CUSTOMER_REFUND_ADDRESS",
"reason": "Customer cancellation",
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/invoices/YOUR_INVOICE_ID/refund",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần reconciliation.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETTìm khoản phân bổ chi trả/v1/marketplace/allocationsChỉ đọc
Ứng viên có phân trang; lọc status (available v.v.), asset_id, vendor_id, store_id và q (nhà bán hàng/đơn hàng/hóa đơn).
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/allocations?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/allocations?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/allocations?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/allocations?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETSố dư sổ cái dự án/v1/marketplace/balancesChỉ đọc
Tổng chính xác nhóm theo tài sản/tài khoản, gồm tiền giữ, khả dụng, giữ chỗ, đã trả, hoa hồng, hoàn tiền và phí mạng. Loại trừ tài khoản cân đối bên ngoài.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/balances?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/balances?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/balances?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/balances?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETNhật ký bất biến/v1/marketplace/ledgerChỉ đọc
Biến động chỉ ghi thêm có phân trang; bộ lọc q tham chiếu/tài khoản, asset_id và vendor_id. Số tiền dùng chuỗi đơn vị nhỏ nhất; không mục nào được sửa hay đánh dấu đã trả thủ công.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/ledger?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/ledger?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/ledger?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/ledger?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETLịch sử chi trả/v1/marketplace/payoutsChỉ đọc
Bản ghi cha có phân trang; lọc state, asset_id, vendor_id hoặc q ID/ký hiệu. Đã trả nghĩa là được xác nhận độc lập, không chỉ phát giao dịch.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/payouts?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/payouts?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/payouts?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/payouts?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTXem trước kế hoạch phân bổ/v1/marketplace/payouts/previewĐọc + ghi
Kế hoạch kế toán chỉ đọc, không giữ chỗ hay có quyền chi tiêu. Phí tối đa là trần do người dùng đặt, không phải phí thực tế ước tính. Chuẩn bị sẽ kiểm tra trực tiếp sau.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | payouts.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/payouts/preview" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"allocation_ids": [
"YOUR_ALLOCATION_ID"
],
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"allocation_ids": [
"YOUR_ALLOCATION_ID"
],
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}`;
const response = await fetch("https://api.example.com/v1/marketplace/payouts/preview", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"allocation_ids": [
"YOUR_ALLOCATION_ID"
],
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/payouts/preview");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"allocation_ids": [
"YOUR_ALLOCATION_ID"
],
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/payouts/preview",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần payouts.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTChuẩn bị chi trả/v1/marketplace/payoutsĐọc + ghi
Giữ chỗ 1–100 ID khoản phân bổ khả dụng trong một tài sản/ví. BTC cần mọi phần chưa trả của từng hóa đơn được chọn trong một lô nhiều đầu ra. Ngân sách là chuỗi đơn vị nhỏ nhất của tài sản phí gốc. Tạo kế hoạch awaiting_approval, không phát giao dịch.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | payouts.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/payouts" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"allocation_ids": [
"YOUR_ALLOCATION_ID"
],
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"allocation_ids": [
"YOUR_ALLOCATION_ID"
],
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}`;
const response = await fetch("https://api.example.com/v1/marketplace/payouts", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"allocation_ids": [
"YOUR_ALLOCATION_ID"
],
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/payouts");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"allocation_ids": [
"YOUR_ALLOCATION_ID"
],
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"fee_tier": "medium"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/payouts",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {
"id": "YOUR_PAYOUT_ID",
"state": "awaiting_approval",
"revision": 1,
"plan_hash": "RETAINED_PLAN_HASH",
"plan": {
"amount_atomic": "28800000",
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"items": []
},
"transactions": []
}
}Trường phản hồi
Ghi chú sử dụng
- Cần payouts.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETChi tiết chi trả/v1/marketplace/payouts/{payout_id}Chỉ đọc
Kế hoạch/mã băm bất biến, phiên bản sửa đổi, thời hạn, mục người nhận, các lần thử con được giữ, tiến độ, phí chính xác và liên kết trình khám phá. Không bao giờ có khóa riêng hay byte đã ký.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {
"id": "YOUR_PAYOUT_ID",
"state": "awaiting_approval",
"revision": 1,
"plan_hash": "RETAINED_PLAN_HASH",
"plan": {
"amount_atomic": "28800000",
"maximum_network_fee_atomic": "10000",
"maximum_gas_funding_atomic": "0",
"items": []
},
"transactions": []
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTPhê duyệt và gửi/v1/marketplace/payouts/{payout_id}/approveĐọc + ghi
Ủy quyền rõ ràng cho đúng kế hoạch được lưu trong thời hạn. Xếp hàng cấp gas có giới hạn và giao dịch nhà bán hàng trong nền.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | payouts.approve |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/approve" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
"confirm": true
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
"confirm": true
}`;
const response = await fetch("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/approve", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
"confirm": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/approve");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
"confirm": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/approve",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần payouts.approve. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTXem xét và tiếp tục chi trả/v1/marketplace/payouts/{payout_id}/resumeĐọc + ghi
Chỉ needs_attention. Dùng lại kế hoạch/mã băm được giữ; không bao giờ gửi lại cho người nhận đã xác nhận. Hai nhà cung cấp độc lập phải chứng minh revert EVM chính tắc đủ xác nhận trước khi thay lần con thất bại. Phí trước vẫn tiêu ngân sách đã phê duyệt và mọi mã băm còn trong lịch sử. Giao token không rõ/một phần trả payout_recovery_unverified; tiền giữ chỗ vẫn bị giữ.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | payouts.approve |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/resume" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
"confirm": true
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
"confirm": true
}`;
const response = await fetch("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/resume", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
"confirm": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/resume");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"expected_plan_hash": "COPY_EXACT_PLAN_HASH_FROM_PREPARE",
"confirm": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/resume",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần payouts.approve. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTHủy công việc chưa ký/v1/marketplace/payouts/{payout_id}/cancelĐọc + ghi
Chỉ giải phóng tiền giữ chỗ an toàn chưa ký/chưa gửi. Người nhận đã xác nhận và kiểm toán vẫn giữ. Không thể hủy công việc đã ký/chưa chắc chắn. Revert đã được khôi phục rõ ràng và chứng minh không còn chặn hủy phần công việc chưa ký còn lại.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | payouts.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/cancel" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}`;
const response = await fetch("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/cancel", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/cancel");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/payouts/YOUR_PAYOUT_ID/cancel",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần payouts.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETChính sách chi trả tự động/v1/marketplace/policiesChỉ đọc
Đọc chính sách theo tài sản, revision, next_attempt_at, last_checked_at và last_error an toàn khi chuẩn bị hoặc ủy quyền cần chú ý.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/policies?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/policies?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/policies?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/policies?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": []
}Trường phản hồi
data[]arrayGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTỦy quyền chính sách chi trả/v1/marketplace/policiesĐọc + ghi
Chuỗi đơn vị nhỏ nhất chính xác; minimum <= transfer <= tiền gốc hằng ngày, trần phí/gas <= ngân sách hằng ngày tương ứng. interval_seconds 60–604800; minimum_confirmations 1–100000 theo ngưỡng tối thiểu chuỗi. Revision 0 tạo mới. Chính sách bật có thể gửi mà không cần nhấp thêm; giữ false đến khi đã xem xét.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | policies.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/policies" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"asset_id": "YOUR_ASSET_ID",
"revision": 0,
"enabled": false,
"minimum_atomic": "100000",
"transfer_limit_atomic": "10000000",
"daily_limit_atomic": "30000000",
"fee_limit_atomic": "10000",
"daily_fee_limit_atomic": "30000",
"gas_limit_atomic": "0",
"daily_gas_limit_atomic": "0",
"interval_seconds": 3600,
"minimum_confirmations": 2
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"asset_id": "YOUR_ASSET_ID",
"revision": 0,
"enabled": false,
"minimum_atomic": "100000",
"transfer_limit_atomic": "10000000",
"daily_limit_atomic": "30000000",
"fee_limit_atomic": "10000",
"daily_fee_limit_atomic": "30000",
"gas_limit_atomic": "0",
"daily_gas_limit_atomic": "0",
"interval_seconds": 3600,
"minimum_confirmations": 2
}`;
const response = await fetch("https://api.example.com/v1/marketplace/policies", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"asset_id": "YOUR_ASSET_ID",
"revision": 0,
"enabled": false,
"minimum_atomic": "100000",
"transfer_limit_atomic": "10000000",
"daily_limit_atomic": "30000000",
"fee_limit_atomic": "10000",
"daily_fee_limit_atomic": "30000",
"gas_limit_atomic": "0",
"daily_gas_limit_atomic": "0",
"interval_seconds": 3600,
"minimum_confirmations": 2
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/policies");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"asset_id": "YOUR_ASSET_ID",
"revision": 0,
"enabled": false,
"minimum_atomic": "100000",
"transfer_limit_atomic": "10000000",
"daily_limit_atomic": "30000000",
"fee_limit_atomic": "10000",
"daily_fee_limit_atomic": "30000",
"gas_limit_atomic": "0",
"daily_gas_limit_atomic": "0",
"interval_seconds": 3600,
"minimum_confirmations": 2
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/policies",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần policies.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETWebhook sàn thương mại/v1/marketplace/webhooksChỉ đọc
Tối đa 20 endpoint cùng event_types được hỗ trợ. Không bao giờ trả bí mật ký mã hóa hay văn bản thuần.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/webhooks?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/webhooks?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/webhooks?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/webhooks?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {
"endpoints": [],
"event_types": [
"marketplace.invoice.created",
"marketplace.allocations.available",
"marketplace.allocations.held",
"marketplace.payout.approved",
"marketplace.payout.broadcast",
"marketplace.payout.confirmed",
"marketplace.payout.partial",
"marketplace.payout.failed",
"marketplace.payout.cancelled",
"marketplace.refund.prepared",
"marketplace.refund.confirmed"
]
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTTạo webhook sàn thương mại/v1/marketplace/webhooksĐọc + ghi
Chỉ HTTPS công khai, không có thông tin xác thực, đích riêng hay chuyển hướng. Trả signing_secret một lần trong mỗi phản hồi tạo idempotent được lưu; lưu an toàn. Tách biệt với bí mật IPN cửa hàng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | webhooks.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/webhooks" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"url": "https://shop.example.com/marketplace-events",
"enabled": true,
"events": [
"marketplace.payout.confirmed",
"marketplace.payout.failed"
]
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"url": "https://shop.example.com/marketplace-events",
"enabled": true,
"events": [
"marketplace.payout.confirmed",
"marketplace.payout.failed"
]
}`;
const response = await fetch("https://api.example.com/v1/marketplace/webhooks", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"url": "https://shop.example.com/marketplace-events",
"enabled": true,
"events": [
"marketplace.payout.confirmed",
"marketplace.payout.failed"
]
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/webhooks");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"url": "https://shop.example.com/marketplace-events",
"enabled": true,
"events": [
"marketplace.payout.confirmed",
"marketplace.payout.failed"
]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/webhooks",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần webhooks.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTCập nhật webhook sàn thương mại/v1/marketplace/webhooks/{webhook_id}/updateĐọc + ghi
Thay đổi hủy lần gửi cũ chưa gửi. Bí mật không đổi; payload cũ bất biến không bao giờ được chuyển sang URL mới.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | webhooks.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/update" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"url": "https://shop.example.com/marketplace-events",
"enabled": true,
"events": [
"marketplace.payout.confirmed"
]
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"url": "https://shop.example.com/marketplace-events",
"enabled": true,
"events": [
"marketplace.payout.confirmed"
]
}`;
const response = await fetch("https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/update", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"url": "https://shop.example.com/marketplace-events",
"enabled": true,
"events": [
"marketplace.payout.confirmed"
]
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/update");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1,
"url": "https://shop.example.com/marketplace-events",
"enabled": true,
"events": [
"marketplace.payout.confirmed"
]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/update",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần webhooks.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTVô hiệu hóa webhook sàn thương mại/v1/marketplace/webhooks/{webhook_id}/disableĐọc + ghi
Dừng lần gửi mới; lịch sử sự kiện được lưu vẫn còn.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | webhooks.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/disable" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}`;
const response = await fetch("https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/disable", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/disable");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"revision": 1
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/webhooks/YOUR_WEBHOOK_ID/disable",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần webhooks.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETSự kiện sàn thương mại/v1/marketplace/eventsChỉ đọc
Tham chiếu sự kiện bất biến có phân trang. q tìm theo loại/tham chiếu; status lọc event_type.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/events?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/events?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/events?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/events?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETĐọc sự kiện được lưu giữ/v1/marketplace/events/{event_id}Chỉ đọc
Trả payload sự kiện gốc bất biến, không dựng lại từ số dư hiện tại.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/events/YOUR_EVENT_ID?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/events/YOUR_EVENT_ID?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/events/YOUR_EVENT_ID?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/events/YOUR_EVENT_ID?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {
"event_id": "11111111-1111-4111-8111-111111111111",
"event_type": "marketplace.payout.confirmed",
"payload_version": 1,
"project_id": "YOUR_PROJECT_ID",
"occurred_at": "2026-10-06T12:00:00Z",
"data": {
"payout_id": "YOUR_PAYOUT_ID",
"asset_id": "YOUR_ASSET_ID",
"amount_atomic": "28800000",
"transactions": [
{
"transaction_id": "EXAMPLE_TRANSACTION_ID",
"explorer_url": "https://mempool.space/tx/EXAMPLE_TRANSACTION_ID"
}
]
}
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETLịch sử gửi của sàn thương mại/v1/marketplace/webhook-deliveriesChỉ đọc
Lần gửi, loại sự kiện, số lần thử và kết quả cuối có phân trang. Lọc status pending/sending/succeeded/failed/cancelled; q theo loại sự kiện.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/webhook-deliveries?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/webhook-deliveries?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/webhook-deliveries?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/webhook-deliveries?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Trường phản hồi
Ghi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETChi tiết lần gửi/v1/marketplace/webhook-deliveries/{delivery_id}Chỉ đọc
URL gốc, payload được lưu, kết quả HTTP và lỗi an toàn; không có bí mật ký.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | marketplace.read |
Tham số truy vấn
pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
per_pagetùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
qtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
statustùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
store_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
vendor_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
asset_idtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
fromtùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
totùy chọnChỉ dùng bộ lọc được ghi trong tài liệu cho tài nguyên này. Danh sách phân trang mặc định 25 và cho phép tối đa 100 dòng.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID?project_id=YOUR_PROJECT_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID?project_id=YOUR_PROJECT_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID?project_id=YOUR_PROJECT_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID?project_id=YOUR_PROJECT_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần marketplace.read. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
POSTGửi lại cùng sự kiện/v1/marketplace/webhook-deliveries/{delivery_id}/resendĐọc + ghi
Chỉ lần gửi đã kết thúc và endpoint đang hoạt động không đổi; tối đa 20 lần thử lại thủ công. Dùng lại event_id. Thông báo thất bại không bao giờ cho phép thanh toán lần hai.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | bắt buộc | 16–128 chữ, số, -, _ hoặc .; lưu bền vững cùng yêu cầu chính xác này |
| Tham số | Kiểu / vị trí | Quy tắc |
|---|---|---|
| permission | credential scope | webhooks.write |
Yêu cầu
: "${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 operation.
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID/resend" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Idempotency-Key: marketplace-request-1042' \
--header 'Content-Type: application/json' \
--data-raw '{
"project_id": "YOUR_PROJECT_ID",
"confirm": true
}'// 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 operation.
const body = `{
"project_id": "YOUR_PROJECT_ID",
"confirm": true
}`;
const response = await fetch("https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID/resend", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Idempotency-Key": "marketplace-request-1042",
"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 operation.
$body = <<<'JSON'
{
"project_id": "YOUR_PROJECT_ID",
"confirm": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID/resend");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: marketplace-request-1042", "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 operation.
headers = {
"Idempotency-Key": "marketplace-request-1042",
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"project_id": "YOUR_PROJECT_ID",
"confirm": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/webhook-deliveries/YOUR_DELIVERY_ID/resend",
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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {}
}Trường phản hồi
dataobjectGhi chú sử dụng
- Cần webhooks.write. Ví dụ phản hồi hiển thị một số trường; GET tài nguyên để lấy toàn bộ bằng chứng được lưu giữ.
- Mọi POST cần Idempotency-Key dài 16–128 ký tự đã được lưu bền vững (chữ, số, -, _ hoặc .). Dùng lại cùng khóa và chỉ dẫn JSON sau khi hết thời gian chờ. Chỉ dẫn khác trả 409. Phản hồi hoàn tất được lưu 30 ngày; khóa cũ trở thành bản ghi đánh dấu không thể dùng lại. Không bao giờ đổi khóa chỉ để vượt qua kết quả chưa chắc chắn.
- Khóa có danh sách dự án, giới hạn cửa hàng hóa đơn tùy chọn, thời hạn, danh sách IP cho phép và hạn mức 1–600/phút (mặc định 60). HTTP 429 có Retry-After. Khóa giới hạn cửa hàng không thể thấy nhà bán hàng, số dư dự án, sổ cái, chi trả hay cài đặt. Chỉ giữ thông tin xác thực chi tiêu trên máy chủ tin cậy, không trong trình duyệt hay ứng dụng di động đã phân phối.
Lỗi
GETLiệt kê ngoại lệ thanh toán/v1/projects/{project_id}/reconciliationChỉ đọc
Một hàng đợi xem xét có phân trang cho thanh toán thiếu, thừa, muộn, bị tái tổ chức hoặc mơ hồ, lần gửi thất bại và phương thức bị tắt/hết hạn. Trường hợp được nhà vận hành xác nhận mở lại khi có bằng chứng mới.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
Tham số đường dẫn
Tham số truy vấn
reasonstringunderpaid, overpaid, late, reorged, ambiguous, delivery_failed, disabled_method hoặc expired_method.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation?status=open&page=1" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation?status=open&page=1", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation?status=open&page=1");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation?status=open&page=1",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{"data":[],"pagination":{"page":1,"per_page":25,"total":0,"has_more":false},"counts":{"open":0,"resolved":0}}Trường phản hồi
data[]object[]luôn luôn
Trường hợp cập nhật mới nhất ở đầu. Dùng invoice_id, không dùng id nội bộ, trong URL chi tiết nhà bán hàng.
idUUIDluôn luônID bản ghi nội bộ / UUID hóa đơn hiển thị cho khách hàng. invoice_id khớp payload callback.
invoice_idUUIDluôn luônID bản ghi nội bộ / UUID hóa đơn hiển thị cho khách hàng. invoice_id khớp payload callback.
paginationobjectluôn luôn
page (1–40001), per_page (25), tổng dòng khớp, has_more.
Ghi chú sử dụng
- Chỉ đọc, giới hạn theo dự án và tính vào hạn mức thông tin xác thực. Quyết định tài chính và hoàn tiền vẫn chỉ có trong bảng điều khiển.
- Dòng gồm id (UUID nội bộ), invoice_id (UUID công khai, giống callback), thông tin cửa hàng, số tiền/loại tiền pháp định gốc, invoice_status, trạng thái trường hợp, lý do, revision và updated_at. Dùng invoice_id trong endpoint chi tiết nhà bán hàng.
- Phát hiện tự động theo cửa sổ theo dõi hóa đơn ban đầu; Quét lại kéo dài quan sát thêm một giờ mà không bật trang thanh toán. Phương thức sau quyết toán/đã hủy tiếp tục được theo dõi trong cửa sổ đó.
Lỗi
GETĐọc bằng chứng đối soát/v1/projects/{project_id}/reconciliation/{invoice_id}Chỉ đọc
Trả hóa đơn, trường hợp, tổng chính xác theo phương thức và số tiền có thể hoàn, giao dịch đã quan sát, lịch sử gửi, quyết định nhà bán hàng và các giao dịch hoàn tiền liên kết. Không bao giờ cung cấp khóa ký hay bí mật callback.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
Tham số đường dẫn
Tham số truy vấn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation/YOUR_PUBLIC_INVOICE_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation/YOUR_PUBLIC_INVOICE_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation/YOUR_PUBLIC_INVOICE_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/reconciliation/YOUR_PUBLIC_INVOICE_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{"invoice":{"invoice_id":"YOUR_PUBLIC_INVOICE_ID","status":"processing"},"case":{"status":"open","reasons":["underpaid"],"revision":1},"methods":[],"history":[],"history_pagination":{"page":1,"per_page":25,"total":0},"refunds":[],"observations":[],"deliveries":[]}Trường phản hồi
invoiceobjectluôn luôn
Hóa đơn nhà bán hàng đầy đủ: trường tóm tắt, metadata riêng và payment_intents. Không bọc trong data.
idUUIDluôn luônUUID hóa đơn nội bộ. Không dùng trong đường dẫn chi tiết nhà bán hàng hay trang thanh toán.
invoice_idUUIDluôn luônUUID hóa đơn công khai dùng trong đường dẫn chi tiết nhà bán hàng và trang thanh toán.
emailstring | nullluôn luônEmail khách hàng chỉ dành cho nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về.
customer_namestring | nullluôn luônTên hiển thị suy ra từ metadata riêng firstname, lastname và company.
customer_addressstring | nullluôn luônĐịa chỉ một dòng dành cho nhà bán hàng, suy ra từ metadata riêng company, street, street2, zip, city, country, countryiso2 và vatid.
exchange_rate_spread_percentdecimal stringluôn luônChênh lệch báo giá đã khóa: ghi đè lúc tạo hoặc mặc định cửa hàng khi bỏ qua. Áp dụng trước làm tròn lên; không bao giờ thay đổi trên hóa đơn này.
underpayment_tolerance_percentdecimal stringluôn luônTỷ lệ thiếu tiền được chấp nhận bất biến, chụp lưu khi tạo hóa đơn.
amount_statusamount statusluôn luônnone, partial, paid hoặc overpaid. Hóa đơn số tiền bằng không được cho phép rõ ràng sẽ quyết toán với none và không có phương thức thanh toán.
winning_payment_intent_idUUID | nullluôn luônPhương thức thanh toán dùng để xử lý hóa đơn, khi đã chọn.
monitoring_expires_atRFC 3339 timestampluôn luônMốc kết thúc theo dõi muộn được cấu hình xa nhất trong các phương thức thanh toán.
ipn_urlstring | nullluôn luônĐích IPN có hiệu lực theo hóa đơn. Chỉ phản hồi nhà bán hàng; không có trên trang thanh toán công khai.
cancel_urlstring | nullluôn luônURL trả về có hiệu lực dùng khi thanh toán kết thúc mà chưa thành công.
redirect_automaticallybooleanluôn luônTrang thanh toán có nên tự chuyển hướng sau thành công hay không.
metadataobjectluôn luônMetadata nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về. Công cụ thanh toán trong bảng điều khiển thêm nguồn gốc payment_tool (id, kind, title, pricing, requested_amount, request_id); điều này không chứng minh thanh toán. Xác thực callback và hoàn tất invoice.settled một lần mỗi invoice_id.Chi tiết
Metadata nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về. Công cụ thanh toán trong bảng điều khiển thêm nguồn gốc payment_tool (id, kind, title, pricing, requested_amount, request_id); điều này không chứng minh thanh toán. Xác thực callback và hoàn tất invoice.settled một lần mỗi invoice_id.
payment_intents[]object[]luôn luôn
Phương thức thanh toán đã báo giá và trạng thái theo dõi.
payment_railonchain | lightningluôn luônCách truyền thanh toán hóa đơn. Bitcoin trên chuỗi và Lightning có thể cùng asset_id; dùng id ý định cộng trường này, không chỉ ký hiệu. Trường này khác payment_rail máy quét trong danh mục tài sản.Chi tiết
Cách truyền thanh toán hóa đơn. Bitcoin trên chuỗi và Lightning có thể cùng asset_id; dùng id ý định cộng trường này, không chỉ ký hiệu. Trường này khác payment_rail máy quét trong danh mục tài sản.
bolt11string | nullluôn luônYêu cầu thanh toán Lightning, nếu không là null. Thanh toán yêu cầu này bằng ví Lightning, không bao giờ gửi tiền trên chuỗi đến mã băm thanh toán của nó.
asset_decimalsintegerluôn luônĐộ chính xác đơn vị nhỏ nhất. Lightning BTC dùng 11 (millisatoshi), không phải 8 của Bitcoin trên chuỗi. Báo giá theo satoshi nguyên; khoản nhận giữ độ chính xác millisatoshi.
quote_ratedecimal stringluôn luônSố đơn vị tài sản cho một đơn vị tiền tệ hóa đơn, gồm chênh lệch đã khóa. Ví dụ 1.02 USDC mỗi USD. Không phải tỷ giá nghịch đảo.
quote_detailsobject | nullluôn luônNguồn gốc báo giá đã khóa: reference_rate trước chênh lệch, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at và asset_fetched_at. Null trên hóa đơn cũ; không tạo giá trị lịch sử giả.Chi tiết
Nguồn gốc báo giá đã khóa: reference_rate trước chênh lệch, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at và asset_fetched_at. Null trên hóa đơn cũ; không tạo giá trị lịch sử giả.
expected_amountdecimal stringluôn luônSố tài sản chính xác đã khóa phải trả sau chênh lệch và làm tròn lên. Từ 4.1.1, stablecoin tiền pháp định được nhận diện và xác minh (như USDC, USDT, DAI, USDS, EURC) làm tròn lên tối đa hai chữ số thập phân; 1.321 thành 1.33, không bao giờ 1.32. Đây là số tiền dự kiến ngay cả với dung sai không. Tài sản khác giữ độ chính xác thích ứng. Hóa đơn hiện có không bao giờ được định giá lại.Chi tiết
Số tài sản chính xác đã khóa phải trả sau chênh lệch và làm tròn lên. Từ 4.1.1, stablecoin tiền pháp định được nhận diện và xác minh (như USDC, USDT, DAI, USDS, EURC) làm tròn lên tối đa hai chữ số thập phân; 1.321 thành 1.33, không bao giờ 1.32. Đây là số tiền dự kiến ngay cả với dung sai không. Tài sản khác giữ độ chính xác thích ứng. Hóa đơn hiện có không bao giờ được định giá lại.
minimum_payment_amountdecimal stringluôn luônSố tiền nhỏ nhất được chấp nhận là đã trả sau khi áp dụng dung sai hóa đơn.
minimum_payment_amount_atomicinteger stringluôn luônNgưỡng được chấp nhận chính xác theo đơn vị nhỏ nhất của tài sản.
destination_addressstringluôn luônĐịa chỉ nhận trên chuỗi hoặc mã băm thanh toán 64 ký tự với Lightning. Dùng bolt11 để thanh toán Lightning; mã băm không phải địa chỉ Bitcoin.
destination_tagstring | nullluôn luônTham chiếu thanh toán công khai bắt buộc khi hệ thống sử dụng: destination tag XRP, memo ID Stellar hoặc bình luận hóa đơn TON. Null với hệ thống dùng địa chỉ riêng.
caseobject | nullluôn luôn
Trường hợp hiện tại với trạng thái, lý do, phiên bản sửa đổi và dấu thời gian; null khi không có ngoại lệ. Loại trừ bằng chứng nội bộ.
methods[]object[]luôn luônid, wallet_id, asset_id, symbol, chain, decimals, expected_atomic, received_atomic, confirmed_atomic, refundable_atomic, address, tag, monitor_error, last_checked_at, monitoring_expires_at và spending_supported. Số tiền theo đơn vị nhỏ nhất là chuỗi.Chi tiết
id, wallet_id, asset_id, symbol, chain, decimals, expected_atomic, received_atomic, confirmed_atomic, refundable_atomic, address, tag, monitor_error, last_checked_at, monitoring_expires_at và spending_supported. Số tiền theo đơn vị nhỏ nhất là chuỗi.
history[]object[]luôn luôn25 quyết định mới nhất cho trang này: id, action, note, actor, result, created_at.
history_paginationobjectluôn luôn
page, per_page (25), total. Chỉ lịch sử quyết định được phân trang theo page.
refunds[]object[]luôn luôn100 khoản hoàn tiền mới nhất: id, payment_intent_id, amount_atomic, destination, status, request, treasury_intent_id, transfer_status, created_at và transactions (id/status). Gửi hoàn tiền chỉ có trong bảng điều khiển.Chi tiết
100 khoản hoàn tiền mới nhất: id, payment_intent_id, amount_atomic, destination, status, request, treasury_intent_id, transfer_status, created_at và transactions (id/status). Gửi hoàn tiền chỉ có trong bảng điều khiển.
observations[]object[]luôn luôn100 mục mới nhất: payment_intent_id, transaction_id, event_index, amount, status, confirmations, observed_at, symbol, chain và disabled_at_detection. Có explorer_name/explorer_url khi được hỗ trợ.Chi tiết
100 mục mới nhất: payment_intent_id, transaction_id, event_index, amount, status, confirmations, observed_at, symbol, chain và disabled_at_detection. Có explorer_name/explorer_url khi được hỗ trợ.
deliveries[]object[]luôn luôn50 mục mới nhất: id, kind, status, attempts, response_status, error, next_attempt_at, event_type và created_at. Không có bí mật callback.
Ghi chú sử dụng
- case là null khi hóa đơn chưa phát sinh ngoại lệ. Trả 100 quan sát và 50 lần gửi gần nhất; lịch sử quyết định có phân trang.
- refundable_atomic cần ít nhất một xác nhận mạng, loại trừ tiền đã giữ chỗ hoàn tiền và không hứa hẹn số tiền ví có thể chi tiêu. Báo giá trực tiếp còn xác thực mức sẵn sàng của ví, số dư nguồn và phí.
- Hoàn tiền đã phát nghĩa là đã gửi tới endpoint chuỗi, không phải khách hàng đã nhận được xác nhận độc lập. Phí tính thêm và phí xử lý tiền pháp định không tự được ghi có khi hoàn tiền.
- Menu dự án trong bảng điều khiển → Cần chú ý cung cấp hủy, chấp nhận, từ chối, mở lại, xem xét, ghi chú, Quét lại, thử gửi lại và hoàn tiền trên chuỗi được hỗ trợ. Quyết định dùng phiên bảo vệ CSRF, request_id duy nhất, phiên bản trường hợp hiện tại, ghi chú bắt buộc và xác nhận rõ ràng; token bearer không thể gọi các thao tác thay đổi này.
Lỗi
GETKhám phá dịch vụ API/Công khai
Phản hồi lớp biên máy chủ API được quản lý, xác nhận vai trò API công khai v1. Phản hồi này do proxy được quản lý tạo, không phải bộ định tuyến Axum của nhà bán hàng.
Xác thực & header
Công khai
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/"// Node.js 18+ · run on your server, never in browser code.
const response = await fetch("https://api.example.com/", {
method: "GET",
headers: {},
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.
$ch = curl_init("https://api.example.com/");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://api.example.com/",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"service": "Wholly Crypto API",
"status": "ready",
"version": "v1"
}Trường phản hồi
Ghi chú sử dụng
- Không cần token bearer.
- Chỉ tên máy chủ API được quản lý bảo đảm phản hồi gốc chính xác này.
Lỗi
GETTình trạng dịch vụ/healthzCông khai
Kiểm tra khả năng truy cập ứng dụng và ping cơ sở dữ liệu trong hai giây. Dùng để giám sát, không thay thế trạng thái hóa đơn.
Xác thực & header
Công khai
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/healthz"// Node.js 18+ · run on your server, never in browser code.
const response = await fetch("https://api.example.com/healthz", {
method: "GET",
headers: {},
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.
$ch = curl_init("https://api.example.com/healthz");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://api.example.com/healthz",
method="GET", headers=headers)
# 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))Phản hồi 200 healthy; 503 database unavailable
Phản hồi ví dụ
{
"status": "ok",
"database": "ok",
"version": "0.1.0"
}Trường phản hồi
Ghi chú sử dụng
- Không cần token bearer.
- Giá trị version là phiên bản gói đang chạy, không phải phiên bản đường dẫn API.
Lỗi
GETLiệt kê tài sản thanh toán của dự án/v1/projects/{project_id}/payment-assetsChỉ đọc
Liệt kê tài sản gốc và token đã xác minh cùng chính sách dự án, trạng thái sẵn sàng của ví chuỗi và khả năng quét/số dư đã cài. scanner_ready là điều kiện bản dựng adapter, không phải kết quả đồng thuận endpoint trực tiếp. Từ 6.0.6, tạo hóa đơn giữ phương thức đã cấu hình khi máy quét gián đoạn. Xác minh nhận tiền vẫn cần ngưỡng nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1).
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Accept: application/json'// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Accept": "application/json"
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Accept: application/json"],
]);
$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
headers = {
"Accept": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [
{
"asset": {
"id": "10000000-0000-4000-8000-000000000003",
"asset_key": "eip155:1/slip44:60",
"chain_slug": "ethereum",
"network": "mainnet",
"caip_network_id": "eip155:1",
"caip_asset_id": "eip155:1/slip44:60",
"asset_kind": "native",
"payment_rail": "evm-native",
"symbol": "ETH",
"name": "Ethereum",
"decimals": 18,
"contract_address": null,
"coingecko_id": "ethereum",
"icon_path": "/assets/coingecko/ethereum.png",
"token_standard": null,
"metadata_verified_at": null,
"payment_supported": true,
"scanner_ready": true,
"balance_ready": true,
"default_finality_mode": "confirmations",
"default_required_confirmations": 12,
"default_monitoring_minutes": 60
},
"policy": {
"enabled": true,
"finality_mode": "confirmations",
"required_confirmations": 12,
"monitoring_minutes": 60,
"late_monitoring_days": 30
},
"wallet": null,
"wallet_readiness": "wallet_missing",
"receive_readiness": { "ready": false, "invoice_creatable": false, "checked_at": "2026-09-16T09:00:00Z", "issues": [{ "chain_slug": "ethereum", "asset_id": "10000000-0000-4000-8000-000000000003", "asset_ticker": "ETH", "reason_code": "wallet_missing", "message": "ethereum / ETH: Create a project wallet for this chain.", "action": "wallets" }] }
}
]
}Trường phản hồi
data[]object[]
assetobjectluôn luôn
Tài sản gốc hoặc token đã xác minh được lưu bền vững.
idUUIDluôn luônMã định danh tài sản thanh toán bền vững được tuyến chính sách dự án và cửa hàng sử dụng.
payment_railstringluôn luônHệ thống xử lý lúc chạy: utxo, evm-native, solana-native, account-native, privacy-native hoặc token-transfer.
contract_addressstring | nullluôn luônHợp đồng ERC-20 hoặc mint SPL chính tắc cho token; null với tài sản gốc.
coingecko_idstring | nullluôn luônDanh tính khám phá/định giá. Null với hợp đồng tùy chỉnh; không bao giờ suy ra giá thị trường từ mã token. Chỉ metadata CoinGecko không bao giờ khiến token có thể được chọn.
custom_tokenbooleanluôn luônHợp đồng tùy chỉnh đã xác minh trên chuỗi với định giá USD cố định hoặc pool DEX được chọn theo phạm vi dự án.
token_standarderc20 | spl-token | nullluôn luônTiêu chuẩn token đã xác minh dùng lúc chạy; null với tài sản gốc.
metadata_verified_attimestamp | nullluôn luônThời điểm xác minh metadata trên chuỗi cho token được đưa vào sử dụng.
payment_supportedbooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
scanner_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
balance_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
default_finality_modeconfirmations | finalizedluôn luônMô hình hoàn tất mặc định được chính sách dự án mới kế thừa.
policyobject | nullluôn luôn
Chính sách kích hoạt/hoàn tất dự án, hoặc null nếu chưa cấu hình. Gồm custom_price_mode (fixed/dex), custom_price_usd (chuỗi thập phân cố định hoặc null), custom_dex_pair (pool đã chọn hoặc null) và custom_dex (dex_id, quote_symbol, price_usd hiện tại hoặc null, liquidity_usd, fetched_at, last_error). Các cửa hàng trong dự án này dùng chung định giá tùy chỉnh.Chi tiết
Chính sách kích hoạt/hoàn tất dự án, hoặc null nếu chưa cấu hình. Gồm custom_price_mode (fixed/dex), custom_price_usd (chuỗi thập phân cố định hoặc null), custom_dex_pair (pool đã chọn hoặc null) và custom_dex (dex_id, quote_symbol, price_usd hiện tại hoặc null, liquidity_usd, fetched_at, last_error). Các cửa hàng trong dự án này dùng chung định giá tùy chỉnh.
finality_modeconfirmations | finalizedbắt buộcChính sách hoàn tất được hệ thống tài sản hỗ trợ. finalized cần required_confirmations=1.
required_confirmationsintegerbắt buộcHệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.Chi tiết
Hệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.
walletobject | nullluôn luôn
Ví dự án không lưu ký của chuỗi. Token dùng chung ví gốc của chuỗi.
backup_confirmed_attimestamp | nullluôn luônKhác null sau khi nhà vận hành xác nhận sao lưu khôi phục.
activation_requiredbooleanluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
activation_verified_attimestamp|nullluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
receive_readinessobject | null5.5.0+
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.Chi tiết
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
monero_wallet_rpcMoneroWalletRpcBinding | nullluôn luônTrạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.Chi tiết
Trạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.
last_secret_revealed_attimestamp|nullluôn luônMetadata kiểm toán việc hiển thị bí mật phía bảng điều khiển.
balances[]object[]luôn luôn
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.Chi tiết
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.
active_store_countintegerluôn luônSố cửa hàng đang bật hiện chọn tài sản này. Đây là dữ liệu thể hiện việc chấp nhận; theo dõi số dư chỉ đọc vẫn độc lập.
active_store_ids[]UUID[]luôn luônCửa hàng đang bật trong dự án này hiện chấp nhận tài sản. Cho phép lọc cửa hàng cục bộ chính xác mà không cần yêu cầu API khác.
tracking_activebooleanluôn luônVí có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.Chi tiết
Ví có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.
balancedecimal string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
balance_atomicinteger string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
statuspending | refreshing | fresh | stale | errorluôn luônTrạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.Chi tiết
Trạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.
balance_statuspending | refreshing | fresh | stale | error | unknownluôn luônĐộ mới bộ nhớ đệm tổng hợp; unknown là giá trị dự phòng an toàn và không trạng thái nào chứng minh quyết toán hóa đơn.
balance_checked_attimestamp | nullluôn luônLần kiểm tra số dư thành công liên quan cũ nhất được thể hiện trong tổng hợp.
recent_payments[]object[]luôn luôn
Tối đa ba quan sát hợp lệ mới nhất ở trạng thái detected, confirming hoặc final được gán cho đúng ví này.
statusdetected | confirming | finalluôn luônTrạng thái quan sát hợp lệ hiện tại. Loại trừ quan sát reorged, replaced và invalid.
wallet_readinessreadiness enumluôn luônunsupported, project_disabled, project_asset_disabled, store_disabled, store_asset_disabled, wallet_missing, wallet_pending, wallet_disabled, wallet_error, backup_required, account_activation_required, external_wallet_rpc_required hoặc ready.Chi tiết
unsupported, project_disabled, project_asset_disabled, store_disabled, store_asset_disabled, wallet_missing, wallet_pending, wallet_disabled, wallet_error, backup_required, account_activation_required, external_wallet_rpc_required hoặc ready.
receive_readinessobject | null5.5.0+
Đánh giá thiết lập nhận tiền dự án dùng chung. Gồm kiểm tra ví và nhà cung cấp máy quét độc lập, tách biệt độ mới số dư và gas gửi tiền. Null nếu chưa có chính sách dự án. Tiền tệ/tỷ giá hóa đơn được kiểm tra khi tạo hóa đơn.Chi tiết
Đánh giá thiết lập nhận tiền dự án dùng chung. Gồm kiểm tra ví và nhà cung cấp máy quét độc lập, tách biệt độ mới số dư và gas gửi tiền. Null nếu chưa có chính sách dự án. Tiền tệ/tỷ giá hóa đơn được kiểm tra khi tạo hóa đơn.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
Ghi chú sử dụng
- Token có thể được liệt kê toàn cục nhưng vẫn không chọn được khi scanner_ready hoặc payment_supported là false.
- Ma trận khả năng nhà vận hành cũng yêu cầu đúng vai trò endpoint máy quét; endpoint khỏe mạnh phục vụ API không tương thích không được tính.
- Token dùng chung ví dự án của chuỗi gốc; không tạo thêm cụm từ seed.
- Tóm tắt ví nhúng chỉ thể hiện mức sẵn sàng và để số dư rỗng; dùng GET /v1/projects/{project_id}/wallets để có số dư đầy đủ hơn.
Lỗi
PUTCập nhật chính sách tài sản của dự án/v1/projects/{project_id}/payment-assets/{asset_id}Đọc + ghi
Tạo hoặc thay chính sách dự án cho một tài sản bền vững và trả danh sách tài sản dự án đã làm mới. Tắt chuỗi gốc khiến tài sản gốc và token không dùng được cho hóa đơn mới, nhưng giữ chính sách token, ví và lựa chọn cửa hàng để có thể tiếp tục về sau.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | bắt buộc | application/json |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request PUT \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets/YOUR_ASSET_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Content-Type: application/json' \
--data-raw '{
"enabled": true,
"finality_mode": "confirmations",
"required_confirmations": 2,
"monitoring_minutes": 60,
"late_monitoring_days": 30
}'// 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");
const body = `{
"enabled": true,
"finality_mode": "confirmations",
"required_confirmations": 2,
"monitoring_minutes": 60,
"late_monitoring_days": 30
}`;
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets/YOUR_ASSET_ID", {
method: "PUT",
headers: {
"Authorization": `Bearer ${token}`,
"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'); }
$body = <<<'JSON'
{
"enabled": true,
"finality_mode": "confirmations",
"required_confirmations": 2,
"monitoring_minutes": 60,
"late_monitoring_days": 30
}
JSON;
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets/YOUR_ASSET_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "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
headers = {
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"enabled": true,
"finality_mode": "confirmations",
"required_confirmations": 2,
"monitoring_minutes": 60,
"late_monitoring_days": 30
}""".encode("utf-8")
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-assets/YOUR_ASSET_ID",
method="PUT", 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))Nội dung yêu cầu
finality_modeconfirmations | finalizedbắt buộcChính sách hoàn tất được hệ thống tài sản hỗ trợ. finalized cần required_confirmations=1.
required_confirmationsintegerbắt buộcHệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.Chi tiết
Hệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [
{ "asset": { "id": "ASSET_UUID", "symbol": "USDC", "asset_kind": "token", "scanner_ready": true }, "policy": { "enabled": true, "finality_mode": "confirmations", "required_confirmations": 2, "monitoring_minutes": 60, "late_monitoring_days": 30 }, "wallet_readiness": "ready" }
]
}Trường phản hồi
data[]object[]
assetobjectluôn luôn
Tài sản gốc hoặc token đã xác minh được lưu bền vững.
idUUIDluôn luônMã định danh tài sản thanh toán bền vững được tuyến chính sách dự án và cửa hàng sử dụng.
payment_railstringluôn luônHệ thống xử lý lúc chạy: utxo, evm-native, solana-native, account-native, privacy-native hoặc token-transfer.
contract_addressstring | nullluôn luônHợp đồng ERC-20 hoặc mint SPL chính tắc cho token; null với tài sản gốc.
coingecko_idstring | nullluôn luônDanh tính khám phá/định giá. Null với hợp đồng tùy chỉnh; không bao giờ suy ra giá thị trường từ mã token. Chỉ metadata CoinGecko không bao giờ khiến token có thể được chọn.
custom_tokenbooleanluôn luônHợp đồng tùy chỉnh đã xác minh trên chuỗi với định giá USD cố định hoặc pool DEX được chọn theo phạm vi dự án.
token_standarderc20 | spl-token | nullluôn luônTiêu chuẩn token đã xác minh dùng lúc chạy; null với tài sản gốc.
metadata_verified_attimestamp | nullluôn luônThời điểm xác minh metadata trên chuỗi cho token được đưa vào sử dụng.
payment_supportedbooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
scanner_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
balance_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
default_finality_modeconfirmations | finalizedluôn luônMô hình hoàn tất mặc định được chính sách dự án mới kế thừa.
policyobject | nullluôn luôn
Chính sách kích hoạt/hoàn tất dự án, hoặc null nếu chưa cấu hình. Gồm custom_price_mode (fixed/dex), custom_price_usd (chuỗi thập phân cố định hoặc null), custom_dex_pair (pool đã chọn hoặc null) và custom_dex (dex_id, quote_symbol, price_usd hiện tại hoặc null, liquidity_usd, fetched_at, last_error). Các cửa hàng trong dự án này dùng chung định giá tùy chỉnh.Chi tiết
Chính sách kích hoạt/hoàn tất dự án, hoặc null nếu chưa cấu hình. Gồm custom_price_mode (fixed/dex), custom_price_usd (chuỗi thập phân cố định hoặc null), custom_dex_pair (pool đã chọn hoặc null) và custom_dex (dex_id, quote_symbol, price_usd hiện tại hoặc null, liquidity_usd, fetched_at, last_error). Các cửa hàng trong dự án này dùng chung định giá tùy chỉnh.
finality_modeconfirmations | finalizedbắt buộcChính sách hoàn tất được hệ thống tài sản hỗ trợ. finalized cần required_confirmations=1.
required_confirmationsintegerbắt buộcHệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.Chi tiết
Hệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.
walletobject | nullluôn luôn
Ví dự án không lưu ký của chuỗi. Token dùng chung ví gốc của chuỗi.
backup_confirmed_attimestamp | nullluôn luônKhác null sau khi nhà vận hành xác nhận sao lưu khôi phục.
activation_requiredbooleanluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
activation_verified_attimestamp|nullluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
receive_readinessobject | null5.5.0+
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.Chi tiết
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
monero_wallet_rpcMoneroWalletRpcBinding | nullluôn luônTrạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.Chi tiết
Trạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.
last_secret_revealed_attimestamp|nullluôn luônMetadata kiểm toán việc hiển thị bí mật phía bảng điều khiển.
balances[]object[]luôn luôn
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.Chi tiết
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.
active_store_countintegerluôn luônSố cửa hàng đang bật hiện chọn tài sản này. Đây là dữ liệu thể hiện việc chấp nhận; theo dõi số dư chỉ đọc vẫn độc lập.
active_store_ids[]UUID[]luôn luônCửa hàng đang bật trong dự án này hiện chấp nhận tài sản. Cho phép lọc cửa hàng cục bộ chính xác mà không cần yêu cầu API khác.
tracking_activebooleanluôn luônVí có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.Chi tiết
Ví có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.
balancedecimal string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
balance_atomicinteger string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
statuspending | refreshing | fresh | stale | errorluôn luônTrạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.Chi tiết
Trạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.
balance_statuspending | refreshing | fresh | stale | error | unknownluôn luônĐộ mới bộ nhớ đệm tổng hợp; unknown là giá trị dự phòng an toàn và không trạng thái nào chứng minh quyết toán hóa đơn.
balance_checked_attimestamp | nullluôn luônLần kiểm tra số dư thành công liên quan cũ nhất được thể hiện trong tổng hợp.
recent_payments[]object[]luôn luôn
Tối đa ba quan sát hợp lệ mới nhất ở trạng thái detected, confirming hoặc final được gán cho đúng ví này.
statusdetected | confirming | finalluôn luônTrạng thái quan sát hợp lệ hiện tại. Loại trừ quan sát reorged, replaced và invalid.
wallet_readinessreadiness enumluôn luônunsupported, project_disabled, project_asset_disabled, store_disabled, store_asset_disabled, wallet_missing, wallet_pending, wallet_disabled, wallet_error, backup_required, account_activation_required, external_wallet_rpc_required hoặc ready.Chi tiết
unsupported, project_disabled, project_asset_disabled, store_disabled, store_asset_disabled, wallet_missing, wallet_pending, wallet_disabled, wallet_error, backup_required, account_activation_required, external_wallet_rpc_required hoặc ready.
receive_readinessobject | null5.5.0+
Đánh giá thiết lập nhận tiền dự án dùng chung. Gồm kiểm tra ví và nhà cung cấp máy quét độc lập, tách biệt độ mới số dư và gas gửi tiền. Null nếu chưa có chính sách dự án. Tiền tệ/tỷ giá hóa đơn được kiểm tra khi tạo hóa đơn.Chi tiết
Đánh giá thiết lập nhận tiền dự án dùng chung. Gồm kiểm tra ví và nhà cung cấp máy quét độc lập, tách biệt độ mới số dư và gas gửi tiền. Null nếu chưa có chính sách dự án. Tiền tệ/tỷ giá hóa đơn được kiểm tra khi tạo hóa đơn.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
Ghi chú sử dụng
- Nội dung thay toàn bộ chính sách và từ chối trường không xác định.
- Bật cho dự án tự nó không chọn tài sản cho bất kỳ cửa hàng nào.
Lỗi
GETDuyệt token thanh toán ứng viên/v1/projects/{project_id}/payment-token-candidatesChỉ đọc
Tìm ánh xạ hợp đồng CoinGecko lưu đệm cục bộ chỉ trên chuỗi đã triển khai máy quét hóa đơn token và adapter số dư. Kết quả là ứng viên khám phá, không phải tài sản thanh toán đáng tin.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Tham số truy vấn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-candidates?chain_slug=ethereum&q=USDC&limit=50" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-candidates?chain_slug=ethereum&q=USDC&limit=50", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-candidates?chain_slug=ethereum&q=USDC&limit=50");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-candidates?chain_slug=ethereum&q=USDC&limit=50",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [
{
"coingecko_id": "usd-coin",
"chain_slug": "ethereum",
"symbol": "USDC",
"name": "USDC",
"contract_address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"market_cap_rank": 7,
"icon_path": "/assets/coingecko/usd-coin.png",
"current_price_usd": "1.0001",
"token_standard": "erc20",
"scanner_ready": true,
"registered_asset_id": null,
"project_enabled": false
}
]
}Trường phản hồi
data[]object[]
contract_addressstringluôn luônHợp đồng hoặc mint khớp; được xác minh trên chuỗi trước khi đăng ký.
market_cap_rankinteger | nullluôn luônThứ hạng khám phá, không phải tín hiệu tin cậy hay sẵn sàng thanh toán.
scanner_readybooleanluôn luônChỉ true với ứng viên trên hệ thống token đã triển khai trong bản dựng này.
Ghi chú sử dụng
- Adapter token được hỗ trợ: ERC-20 trên Ethereum, Base, BNB Chain, HyperEVM, Avalanche, Polygon, Arbitrum và Optimism; SPL trên Solana.
- Chuỗi trong danh mục không được hỗ trợ bị từ chối thay vì xuất hiện như có thể chọn.
- Thứ hạng, biểu tượng và giá CoinGecko là dữ liệu khám phá tham khảo.
Lỗi
POSTXác minh và đăng ký token/v1/projects/{project_id}/payment-token-assetsĐọc + ghi
Đưa một ứng viên hiện tại vào sổ đăng ký thanh toán bền vững chỉ sau khi nút đã cấu hình xác minh danh tính chuỗi, danh tính hợp đồng/mint, số chữ số thập phân và truy vấn số dư dùng được. Đăng ký không bao giờ chỉ tin metadata CoinGecko, và mỗi dự án giới hạn 20 tài sản token đăng ký.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | bắt buộc | application/json |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Content-Type: application/json' \
--data-raw '{
"chain_slug": "ethereum",
"coingecko_id": "usd-coin",
"enabled": true
}'// 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");
const body = `{
"chain_slug": "ethereum",
"coingecko_id": "usd-coin",
"enabled": true
}`;
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"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'); }
$body = <<<'JSON'
{
"chain_slug": "ethereum",
"coingecko_id": "usd-coin",
"enabled": true
}
JSON;
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "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
headers = {
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"chain_slug": "ethereum",
"coingecko_id": "usd-coin",
"enabled": true
}""".encode("utf-8")
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets",
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))Nội dung yêu cầu
chain_slugstringbắt buộcethereum, base, bnb-chain, hyperliquid, avalanche, polygon, arbitrum, optimism hoặc solana.
coingecko_idstringbắt buộcDanh tính ứng viên chính xác do tìm kiếm token trả về. Giữ gạch dưới hoặc gạch nối ở đầu, như _ hoặc -6. Không suy ra ID này từ tên hay mã token.Chi tiết
Danh tính ứng viên chính xác do tìm kiếm token trả về. Giữ gạch dưới hoặc gạch nối ở đầu, như _ hoặc -6. Không suy ra ID này từ tên hay mã token.
Phản hồi 201 application/json
Phản hồi ví dụ
{
"data": {
"asset_id": "44444444-4444-4444-8444-444444444444",
"chain_slug": "ethereum",
"coingecko_id": "usd-coin",
"contract_address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"token_standard": "erc20",
"symbol": "USDC",
"name": "USDC",
"decimals": 6,
"enabled": true,
"metadata_verified_at": "2026-08-31T18:00:00Z"
}
}Trường phản hồi
dataobject
Ghi chú sử dụng
- Bật tài sản gốc của chuỗi trong dự án trước khi đăng ký token.
- Dự án có thể đăng ký tối đa 20 tài sản token; ứng viên mới vượt trần trả token_chain_not_ready (409). Dùng lại tài sản đã đăng ký không chiếm thêm suất.
- Xác minh nút có thể lâu hơn đọc danh mục; dùng thời gian chờ ứng dụng khách rõ ràng.
- Sau đăng ký, chọn tài sản cho từng cửa hàng cần cung cấp nó.
Lỗi
GETTìm pool DEX cho token tùy chỉnh/v1/projects/{project_id}/payment-token-dex-poolsChỉ đọc
Tìm tối đa 12 pool đủ điều kiện theo đúng chuỗi và hợp đồng token cơ sở qua DEX Screener, sắp theo thanh khoản. Thao tác này không đăng ký hay bật token.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
Tham số đường dẫn
Tham số truy vấn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-dex-pools?chain_slug=ethereum&contract_address=YOUR_TOKEN_CONTRACT" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-dex-pools?chain_slug=ethereum&contract_address=YOUR_TOKEN_CONTRACT", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-dex-pools?chain_slug=ethereum&contract_address=YOUR_TOKEN_CONTRACT");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-dex-pools?chain_slug=ethereum&contract_address=YOUR_TOKEN_CONTRACT",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{"data":[{"pair_address":"0x2222222222222222222222222222222222222222","dex_id":"uniswap","quote_symbol":"WETH","price_usd":"0.25","liquidity_usd":"250000.00","fetched_at":"2026-09-09T12:00:00Z","url":"https://dexscreener.com/ethereum/0x2222222222222222222222222222222222222222"}]}Trường phản hồi
data[]object[]
pair_addressstringluôn luônMã định danh pool chính xác, ID sàn (ví dụ uniswap/pancakeswap) và mã tài sản ghép cặp chỉ để hiển thị.
dex_idstringluôn luônMã định danh pool chính xác, ID sàn (ví dụ uniswap/pancakeswap) và mã tài sản ghép cặp chỉ để hiển thị.
quote_symbolstringluôn luônMã định danh pool chính xác, ID sàn (ví dụ uniswap/pancakeswap) và mã tài sản ghép cặp chỉ để hiển thị.
price_usddecimal stringluôn luônGiá USD của token cơ sở được yêu cầu và tổng thanh khoản pool. Cần ít nhất $10,000 thanh khoản và một giao dịch trong giờ qua.
liquidity_usddecimal stringluôn luônGiá USD của token cơ sở được yêu cầu và tổng thanh khoản pool. Cần ít nhất $10,000 thanh khoản và một giao dịch trong giờ qua.
fetched_atRFC 3339 timestampluôn luônThời điểm máy chủ lấy quan sát của nhà cung cấp, không phải dấu thời gian giao dịch trên chuỗi.
Ghi chú sử dụng
- Mảng data rỗng nghĩa là không tìm được pool đủ điều kiện. Chỉ trả pool có đúng hợp đồng được yêu cầu làm token cơ sở; không bao giờ giả định giá USD của phía báo giá.
- Niêm yết DEX không phải kiểm toán bảo mật. Thanh khoản tối thiểu và hoạt động gần đây giảm báo giá không dùng được nhưng không ngăn thao túng thị trường.
- Hỗ trợ Uniswap, PancakeSwap và DEX được lập chỉ mục khác nơi máy quét chuỗi hiện có hỗ trợ token. Truy cập API vẫn giới hạn theo dự án và tần suất. Lời gọi nhà cung cấp cũng được tuần tự hóa và điều tiết.
Lỗi
POSTThêm hoặc định giá lại token tùy chỉnh/v1/projects/{project_id}/payment-token-assets/customĐọc + ghi
Xác minh hợp đồng tùy chỉnh bằng nút chuỗi đã cấu hình và đăng ký mà không cần niêm yết CoinGecko. Giá USD cố định hoặc pool DEX tự động được chọn thuộc dự án này, không thuộc mã token hay dự án khác. Lặp cùng danh tính cập nhật giá trong dự án mà không đổi chính sách bật/tắt hiện có.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | bắt buộc | application/json |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request POST \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets/custom" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Content-Type: application/json' \
--data-raw '{
"chain_slug": "ethereum",
"contract_address": "YOUR_VERIFIED_TOKEN_CONTRACT",
"name": "Example token",
"symbol": "EXAMPLE",
"price_usd": "0.25"
}'// 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");
const body = `{
"chain_slug": "ethereum",
"contract_address": "YOUR_VERIFIED_TOKEN_CONTRACT",
"name": "Example token",
"symbol": "EXAMPLE",
"price_usd": "0.25"
}`;
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets/custom", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"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'); }
$body = <<<'JSON'
{
"chain_slug": "ethereum",
"contract_address": "YOUR_VERIFIED_TOKEN_CONTRACT",
"name": "Example token",
"symbol": "EXAMPLE",
"price_usd": "0.25"
}
JSON;
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets/custom");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "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
headers = {
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"chain_slug": "ethereum",
"contract_address": "YOUR_VERIFIED_TOKEN_CONTRACT",
"name": "Example token",
"symbol": "EXAMPLE",
"price_usd": "0.25"
}""".encode("utf-8")
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/payment-token-assets/custom",
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))Nội dung yêu cầu
chain_slugstringbắt buộcethereum, base, bnb-chain, hyperliquid, avalanche, polygon, arbitrum, optimism hoặc solana. Cố định cho hợp đồng này.
contract_addressstringbắt buộcHợp đồng ERC-20 (0x cộng 40 ký tự thập lục phân), hoặc mint SPL cổ điển. Nút xác minh danh tính mạng và số chữ số thập phân chính xác; từ chối số chữ số thập phân và URL RPC do bên gọi cung cấp.Chi tiết
Hợp đồng ERC-20 (0x cộng 40 ký tự thập lục phân), hoặc mint SPL cổ điển. Nút xác minh danh tính mạng và số chữ số thập phân chính xác; từ chối số chữ số thập phân và URL RPC do bên gọi cung cấp.
namestringbắt buộcTên hiển thị (1–80 ký tự) và mã (1–16 chữ/số/dấu chấm/gạch dưới/gạch nối, ký tự đầu là chữ hoặc số). Endpoint này không đổi tên danh tính hiện có.Chi tiết
Tên hiển thị (1–80 ký tự) và mã (1–16 chữ/số/dấu chấm/gạch dưới/gạch nối, ký tự đầu là chữ hoặc số). Endpoint này không đổi tên danh tính hiện có.
symbolstringbắt buộcTên hiển thị (1–80 ký tự) và mã (1–16 chữ/số/dấu chấm/gạch dưới/gạch nối, ký tự đầu là chữ hoặc số). Endpoint này không đổi tên danh tính hiện có.Chi tiết
Tên hiển thị (1–80 ký tự) và mã (1–16 chữ/số/dấu chấm/gạch dưới/gạch nối, ký tự đầu là chữ hoặc số). Endpoint này không đổi tên danh tính hiện có.
price_modefixed | dextùy chọnMặc định fixed để tương thích ngược. DEX dùng pool cụ thể đã khám phá cho đúng chuỗi và hợp đồng.
price_usddecimal stringchế độ fixedGiá trị USD cố định của MỘT token, dương, tối đa 30 chữ số thập phân, tối đa 1000000000000000000000000. Không số mũ hay số dấu phẩy động. Bỏ qua trong chế độ dex.
dex_pair_addressstringchế độ dexĐịa chỉ pool từ payment-token-dex-pools. Bắt buộc ở chế độ dex; bỏ qua ở chế độ fixed. Máy chủ kiểm tra lại danh tính pool, giá, thanh khoản và hoạt động mỗi lần lưu.Chi tiết
Địa chỉ pool từ payment-token-dex-pools. Bắt buộc ở chế độ dex; bỏ qua ở chế độ fixed. Máy chủ kiểm tra lại danh tính pool, giá, thanh khoản và hoạt động mỗi lần lưu.
Phản hồi 200 application/json
Phản hồi ví dụ
{"data":{"asset_id":"44444444-4444-4444-8444-444444444444"}}Trường phản hồi
Ghi chú sử dụng
- Sau đăng ký, chọn asset_id trong endpoint payment-assets của cửa hàng; chỉ đăng ký không bao giờ bật phương thức cửa hàng.
- Token tùy chỉnh và trong danh mục dùng chung giới hạn 20 token mỗi dự án. Cùng hợp đồng trên chuỗi khác nhau là tài sản thanh toán khác nhau.
- Hợp đồng đã có trong danh mục trả 409: dùng đăng ký danh mục để giữ tỷ giá thị trường tự động. Mã tùy chỉnh không bao giờ mượn giá của token trùng tên.
- Giá cố định là ước tính của nhà vận hành. Giá DEX tự động là quan sát giá giao ngay từ pool đã chọn qua DEX Screener, không phải oracle chống thao túng. Chênh lệch cửa hàng và làm tròn lên vẫn áp dụng, cùng tỷ giá tiền pháp định mới. Báo giá đã cấp không đổi.
- Với chế độ DEX, trước hết khám phá pool, rồi gửi price_mode: dex và dex_pair_address, bỏ price_usd. Tác vụ nền dùng chung làm mới pool đã chọn mỗi phút. Kiểm tra thất bại hoặc giá cũ hơn năm phút loại token khỏi báo giá mới; không âm thầm chuyển sang giá cố định hay mã token dự phòng.
- Chỉ chấp nhận ERC-20 tiêu chuẩn và SPL cổ điển. Từ chối Token-2022/phần mở rộng và chuỗi chỉ đồng gốc. Xác minh kỹ thuật không phải kiểm toán bảo mật nhà phát hành/hợp đồng; token thu phí chuyển, điều chỉnh nguồn cung hoặc chặn danh sách có thể hoạt động không tương thích.
- Dùng thời gian chờ ứng dụng khách ít nhất 60 giây. Xác minh có giới hạn và có thể thử nút dự phòng. Đầu vào không hợp lệ trả 400; kiểm tra chuỗi/hợp đồng thất bại trả 422; xung đột danh tính hoặc giới hạn trả 409.
Lỗi
GETLiệt kê phương thức thanh toán của cửa hàng/v1/projects/{project_id}/stores/{store_id}/payment-assetsChỉ đọc
Liệt kê tài sản trên chuỗi trong data và mức sẵn sàng Lightning riêng trong lightning. Phương thức trên chuỗi cần ví chuỗi sẵn sàng. Lightning dùng kết nối nhận bên ngoài đã xác minh được chọn trong cửa hàng, độc lập với ví Bitcoin trên chuỗi.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [
{ "asset": { "id": "ASSET_UUID", "chain_slug": "ethereum", "symbol": "USDC", "asset_kind": "token", "token_standard": "erc20", "scanner_ready": true }, "project_policy": { "enabled": true, "required_confirmations": 12 }, "selected": true, "display_order": 0, "confirmation_policy": { "finality_mode": "confirmations", "project_required_confirmations": 12, "override_required_confirmations": 3, "effective_required_confirmations": 3, "editable": true, "minimum_required_confirmations": 0, "maximum_required_confirmations": 48 }, "wallet": { "id": "WALLET_UUID", "status": "active" }, "wallet_readiness": "ready" }
],
"lightning": { "payment_rail": "lightning", "symbol": "BTC", "asset_decimals": 11, "enabled": true, "ready": true }
}Trường phản hồi
data[]object[]
assetobjectluôn luôn
Tài sản gốc hoặc token đã xác minh mà dự án thấy được.
idUUIDluôn luônMã định danh tài sản thanh toán bền vững được tuyến chính sách dự án và cửa hàng sử dụng.
payment_railstringluôn luônHệ thống xử lý lúc chạy: utxo, evm-native, solana-native, account-native, privacy-native hoặc token-transfer.
contract_addressstring | nullluôn luônHợp đồng ERC-20 hoặc mint SPL chính tắc cho token; null với tài sản gốc.
coingecko_idstring | nullluôn luônDanh tính khám phá/định giá. Null với hợp đồng tùy chỉnh; không bao giờ suy ra giá thị trường từ mã token. Chỉ metadata CoinGecko không bao giờ khiến token có thể được chọn.
custom_tokenbooleanluôn luônHợp đồng tùy chỉnh đã xác minh trên chuỗi với định giá USD cố định hoặc pool DEX được chọn theo phạm vi dự án.
token_standarderc20 | spl-token | nullluôn luônTiêu chuẩn token đã xác minh dùng lúc chạy; null với tài sản gốc.
metadata_verified_attimestamp | nullluôn luônThời điểm xác minh metadata trên chuỗi cho token được đưa vào sử dụng.
payment_supportedbooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
scanner_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
balance_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
default_finality_modeconfirmations | finalizedluôn luônMô hình hoàn tất mặc định được chính sách dự án mới kế thừa.
project_policyobject | nullluôn luôn
Chính sách dự án cha.
finality_modeconfirmations | finalizedbắt buộcChính sách hoàn tất được hệ thống tài sản hỗ trợ. finalized cần required_confirmations=1.
required_confirmationsintegerbắt buộcHệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.Chi tiết
Hệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.
selectedbooleanluôn luônPhương thức này có thuộc cấu hình mong muốn đã lưu của cửa hàng hay không. Nó được cung cấp khi chính sách dự án, ví, adapter đã cài và định giá hợp lệ. Sự cố máy quét tạm thời không loại nó khỏi hóa đơn mới.Chi tiết
Phương thức này có thuộc cấu hình mong muốn đã lưu của cửa hàng hay không. Nó được cung cấp khi chính sách dự án, ví, adapter đã cài và định giá hợp lệ. Sự cố máy quét tạm thời không loại nó khỏi hóa đơn mới.
confirmation_policyobject | nullluôn luôn
Chính sách cửa hàng có hiệu lực cho tài sản đã cấu hình trong dự án. Null khi không có chính sách dự án.
finality_modeconfirmations | finalizedluôn luônQuyết toán dùng số khối có thể cấu hình hay tính hoàn tất mạng.
project_required_confirmationsintegerluôn luônMặc định dự án hiện tại dùng cho hóa đơn tương lai khi không đặt ghi đè cửa hàng.
override_required_confirmationsinteger | nullluôn luônSố riêng cho cửa hàng hoặc null để kế thừa mặc định dự án.
effective_required_confirmationsintegerluôn luônSố mà hóa đơn mới cho cửa hàng và tài sản này sẽ chụp lưu.
minimum_required_confirmationsintegerluôn luônCận dưới bao gồm giá trị biên theo chuỗi; chỉ cung cấp 0 trên hệ thống hỗ trợ chấp nhận ngay khi phát hiện.
walletobject | nullluôn luôn
Ví chuỗi dùng chung cho tài sản gốc và token.
backup_confirmed_attimestamp | nullluôn luônKhác null sau khi nhà vận hành xác nhận sao lưu khôi phục.
activation_requiredbooleanluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
activation_verified_attimestamp|nullluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
receive_readinessobject | null5.5.0+
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.Chi tiết
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
monero_wallet_rpcMoneroWalletRpcBinding | nullluôn luônTrạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.Chi tiết
Trạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.
last_secret_revealed_attimestamp|nullluôn luônMetadata kiểm toán việc hiển thị bí mật phía bảng điều khiển.
balances[]object[]luôn luôn
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.Chi tiết
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.
active_store_countintegerluôn luônSố cửa hàng đang bật hiện chọn tài sản này. Đây là dữ liệu thể hiện việc chấp nhận; theo dõi số dư chỉ đọc vẫn độc lập.
active_store_ids[]UUID[]luôn luônCửa hàng đang bật trong dự án này hiện chấp nhận tài sản. Cho phép lọc cửa hàng cục bộ chính xác mà không cần yêu cầu API khác.
tracking_activebooleanluôn luônVí có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.Chi tiết
Ví có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.
balancedecimal string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
balance_atomicinteger string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
statuspending | refreshing | fresh | stale | errorluôn luônTrạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.Chi tiết
Trạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.
balance_statuspending | refreshing | fresh | stale | error | unknownluôn luônĐộ mới bộ nhớ đệm tổng hợp; unknown là giá trị dự phòng an toàn và không trạng thái nào chứng minh quyết toán hóa đơn.
balance_checked_attimestamp | nullluôn luônLần kiểm tra số dư thành công liên quan cũ nhất được thể hiện trong tổng hợp.
recent_payments[]object[]luôn luôn
Tối đa ba quan sát hợp lệ mới nhất ở trạng thái detected, confirming hoặc final được gán cho đúng ví này.
statusdetected | confirming | finalluôn luônTrạng thái quan sát hợp lệ hiện tại. Loại trừ quan sát reorged, replaced và invalid.
wallet_readinessreadiness enumluôn luônChỉ trạng thái ví/chính sách; dùng receive_readiness cho điều kiện tiên quyết máy quét.
receive_readinessobject | null5.5.0+
Thiết lập nhận tiền dùng chung cộng việc chấp nhận của cửa hàng. Dùng quan sát lưu đệm; không giữ chỗ hay bảo đảm. Tạo hóa đơn kiểm tra lại điều kiện và tỷ giá hóa đơn thực tế.Chi tiết
Thiết lập nhận tiền dùng chung cộng việc chấp nhận của cửa hàng. Dùng quan sát lưu đệm; không giữ chỗ hay bảo đảm. Tạo hóa đơn kiểm tra lại điều kiện và tỷ giá hóa đơn thực tế.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
Ghi chú sử dụng
- selected là cấu hình trên chuỗi; wallet_readiness là điều kiện đủ hiện tại của nó.
- Thành phần lightning trong phản hồi gồm payment_rail: lightning, symbol: BTC, asset_decimals: 11, enabled và ready. Không bao giờ có thông tin xác thực nút. Cấu hình phương thức này trong bảng điều khiển cửa hàng; cập nhật mảng assets không thay đổi Lightning.
- confirmation_policy chỉ áp dụng cho phương thức trên chuỗi. Lightning quyết toán không cần xác nhận khối và cần đủ số tiền BOLT11, không có dung sai thanh toán một phần.
- Phương thức đồng gốc và token trên cùng chuỗi dùng cùng đích hóa đơn cho ví chuỗi đó.
- Tóm tắt ví nhúng chỉ thể hiện mức sẵn sàng và để số dư rỗng; dùng tuyến ví dự án chuyên dụng cho giá trị hiện tại.
Lỗi
PUTThay thế phương thức thanh toán của cửa hàng/v1/projects/{project_id}/stores/{store_id}/payment-assetsĐọc + ghi
Thay nguyên tử toàn bộ tập con tài sản có thứ tự của cửa hàng và trả danh sách đã làm mới. Tài sản bị bỏ khỏi yêu cầu sẽ bỏ chọn.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | bắt buộc | application/json |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request PUT \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Content-Type: application/json' \
--data-raw '{
"assets": [
{
"asset_id": "YOUR_ASSET_ID",
"display_order": 0
}
]
}'// 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");
const body = `{
"assets": [
{
"asset_id": "YOUR_ASSET_ID",
"display_order": 0
}
]
}`;
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets", {
method: "PUT",
headers: {
"Authorization": `Bearer ${token}`,
"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'); }
$body = <<<'JSON'
{
"assets": [
{
"asset_id": "YOUR_ASSET_ID",
"display_order": 0
}
]
}
JSON;
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "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
headers = {
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"assets": [
{
"asset_id": "YOUR_ASSET_ID",
"display_order": 0
}
]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets",
method="PUT", 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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [
{ "asset": { "id": "44444444-4444-4444-8444-444444444444", "symbol": "USDC" }, "selected": true, "display_order": 0, "confirmation_policy": { "finality_mode": "confirmations", "project_required_confirmations": 12, "override_required_confirmations": null, "effective_required_confirmations": 12, "editable": true, "minimum_required_confirmations": 0, "maximum_required_confirmations": 48 }, "wallet_readiness": "ready" }
]
}Trường phản hồi
data[]object[]
assetobjectluôn luôn
Tài sản gốc hoặc token đã xác minh mà dự án thấy được.
idUUIDluôn luônMã định danh tài sản thanh toán bền vững được tuyến chính sách dự án và cửa hàng sử dụng.
payment_railstringluôn luônHệ thống xử lý lúc chạy: utxo, evm-native, solana-native, account-native, privacy-native hoặc token-transfer.
contract_addressstring | nullluôn luônHợp đồng ERC-20 hoặc mint SPL chính tắc cho token; null với tài sản gốc.
coingecko_idstring | nullluôn luônDanh tính khám phá/định giá. Null với hợp đồng tùy chỉnh; không bao giờ suy ra giá thị trường từ mã token. Chỉ metadata CoinGecko không bao giờ khiến token có thể được chọn.
custom_tokenbooleanluôn luônHợp đồng tùy chỉnh đã xác minh trên chuỗi với định giá USD cố định hoặc pool DEX được chọn theo phạm vi dự án.
token_standarderc20 | spl-token | nullluôn luônTiêu chuẩn token đã xác minh dùng lúc chạy; null với tài sản gốc.
metadata_verified_attimestamp | nullluôn luônThời điểm xác minh metadata trên chuỗi cho token được đưa vào sử dụng.
payment_supportedbooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
scanner_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
balance_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
default_finality_modeconfirmations | finalizedluôn luônMô hình hoàn tất mặc định được chính sách dự án mới kế thừa.
project_policyobject | nullluôn luôn
Chính sách dự án cha.
finality_modeconfirmations | finalizedbắt buộcChính sách hoàn tất được hệ thống tài sản hỗ trợ. finalized cần required_confirmations=1.
required_confirmationsintegerbắt buộcHệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.Chi tiết
Hệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.
selectedbooleanluôn luônPhương thức này có thuộc cấu hình mong muốn đã lưu của cửa hàng hay không. Nó được cung cấp khi chính sách dự án, ví, adapter đã cài và định giá hợp lệ. Sự cố máy quét tạm thời không loại nó khỏi hóa đơn mới.Chi tiết
Phương thức này có thuộc cấu hình mong muốn đã lưu của cửa hàng hay không. Nó được cung cấp khi chính sách dự án, ví, adapter đã cài và định giá hợp lệ. Sự cố máy quét tạm thời không loại nó khỏi hóa đơn mới.
confirmation_policyobject | nullluôn luôn
Chính sách cửa hàng có hiệu lực cho tài sản đã cấu hình trong dự án. Null khi không có chính sách dự án.
finality_modeconfirmations | finalizedluôn luônQuyết toán dùng số khối có thể cấu hình hay tính hoàn tất mạng.
project_required_confirmationsintegerluôn luônMặc định dự án hiện tại dùng cho hóa đơn tương lai khi không đặt ghi đè cửa hàng.
override_required_confirmationsinteger | nullluôn luônSố riêng cho cửa hàng hoặc null để kế thừa mặc định dự án.
effective_required_confirmationsintegerluôn luônSố mà hóa đơn mới cho cửa hàng và tài sản này sẽ chụp lưu.
minimum_required_confirmationsintegerluôn luônCận dưới bao gồm giá trị biên theo chuỗi; chỉ cung cấp 0 trên hệ thống hỗ trợ chấp nhận ngay khi phát hiện.
walletobject | nullluôn luôn
Ví chuỗi dùng chung cho tài sản gốc và token.
backup_confirmed_attimestamp | nullluôn luônKhác null sau khi nhà vận hành xác nhận sao lưu khôi phục.
activation_requiredbooleanluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
activation_verified_attimestamp|nullluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
receive_readinessobject | null5.5.0+
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.Chi tiết
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
monero_wallet_rpcMoneroWalletRpcBinding | nullluôn luônTrạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.Chi tiết
Trạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.
last_secret_revealed_attimestamp|nullluôn luônMetadata kiểm toán việc hiển thị bí mật phía bảng điều khiển.
balances[]object[]luôn luôn
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.Chi tiết
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.
active_store_countintegerluôn luônSố cửa hàng đang bật hiện chọn tài sản này. Đây là dữ liệu thể hiện việc chấp nhận; theo dõi số dư chỉ đọc vẫn độc lập.
active_store_ids[]UUID[]luôn luônCửa hàng đang bật trong dự án này hiện chấp nhận tài sản. Cho phép lọc cửa hàng cục bộ chính xác mà không cần yêu cầu API khác.
tracking_activebooleanluôn luônVí có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.Chi tiết
Ví có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.
balancedecimal string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
balance_atomicinteger string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
statuspending | refreshing | fresh | stale | errorluôn luônTrạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.Chi tiết
Trạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.
balance_statuspending | refreshing | fresh | stale | error | unknownluôn luônĐộ mới bộ nhớ đệm tổng hợp; unknown là giá trị dự phòng an toàn và không trạng thái nào chứng minh quyết toán hóa đơn.
balance_checked_attimestamp | nullluôn luônLần kiểm tra số dư thành công liên quan cũ nhất được thể hiện trong tổng hợp.
recent_payments[]object[]luôn luôn
Tối đa ba quan sát hợp lệ mới nhất ở trạng thái detected, confirming hoặc final được gán cho đúng ví này.
statusdetected | confirming | finalluôn luônTrạng thái quan sát hợp lệ hiện tại. Loại trừ quan sát reorged, replaced và invalid.
wallet_readinessreadiness enumluôn luônChỉ trạng thái ví/chính sách; dùng receive_readiness cho điều kiện tiên quyết máy quét.
receive_readinessobject | null5.5.0+
Thiết lập nhận tiền dùng chung cộng việc chấp nhận của cửa hàng. Dùng quan sát lưu đệm; không giữ chỗ hay bảo đảm. Tạo hóa đơn kiểm tra lại điều kiện và tỷ giá hóa đơn thực tế.Chi tiết
Thiết lập nhận tiền dùng chung cộng việc chấp nhận của cửa hàng. Dùng quan sát lưu đệm; không giữ chỗ hay bảo đảm. Tạo hóa đơn kiểm tra lại điều kiện và tỷ giá hóa đơn thực tế.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
Ghi chú sử dụng
- Mảng chấp nhận tối đa 64 tài sản và thứ tự hiển thị duy nhất.
- Lựa chọn là cấu hình mong muốn được lưu và có thể chuẩn bị trước khi sao lưu ví hoặc khi chuỗi tạm dừng. Tạo hóa đơn vẫn chỉ cung cấp phương thức có chính sách dự án, chính sách gốc cha, ví và kiểm tra lúc chạy sẵn sàng.
- Gửi mảng assets rỗng để cấu hình không có phương thức thanh toán.
Lỗi
PUTĐặt chính sách xác nhận cho cửa hàng/v1/projects/{project_id}/stores/{store_id}/payment-assets/{asset_id}/confirmation-policyĐọc + ghi
Đặt hoặc xóa một ghi đè xác nhận riêng cho cửa hàng và trả danh sách phương thức thanh toán cửa hàng đã làm mới. Tài sản phải được chọn cho cửa hàng từ trước. Cấu hình vẫn dùng được khi dự án, cửa hàng, chuỗi hoặc ví tạm dừng.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | bắt buộc | application/json |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request PUT \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets/YOUR_ASSET_ID/confirmation-policy" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Content-Type: application/json' \
--data-raw '{
"strategy": "custom",
"required_confirmations": 0
}'// 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");
const body = `{
"strategy": "custom",
"required_confirmations": 0
}`;
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets/YOUR_ASSET_ID/confirmation-policy", {
method: "PUT",
headers: {
"Authorization": `Bearer ${token}`,
"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'); }
$body = <<<'JSON'
{
"strategy": "custom",
"required_confirmations": 0
}
JSON;
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets/YOUR_ASSET_ID/confirmation-policy");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "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
headers = {
"Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
"strategy": "custom",
"required_confirmations": 0
}""".encode("utf-8")
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/payment-assets/YOUR_ASSET_ID/confirmation-policy",
method="PUT", 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))Nội dung yêu cầu
Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [
{
"asset": { "id": "YOUR_ASSET_ID", "chain_slug": "bitcoin", "symbol": "BTC" },
"selected": true,
"display_order": 0,
"confirmation_policy": {
"finality_mode": "confirmations",
"project_required_confirmations": 2,
"override_required_confirmations": 0,
"effective_required_confirmations": 0,
"editable": true,
"minimum_required_confirmations": 0,
"maximum_required_confirmations": 10000
},
"wallet_readiness": "ready"
}
]
}Trường phản hồi
data[]object[]
assetobjectluôn luôn
Tài sản gốc hoặc token đã xác minh mà dự án thấy được.
idUUIDluôn luônMã định danh tài sản thanh toán bền vững được tuyến chính sách dự án và cửa hàng sử dụng.
payment_railstringluôn luônHệ thống xử lý lúc chạy: utxo, evm-native, solana-native, account-native, privacy-native hoặc token-transfer.
contract_addressstring | nullluôn luônHợp đồng ERC-20 hoặc mint SPL chính tắc cho token; null với tài sản gốc.
coingecko_idstring | nullluôn luônDanh tính khám phá/định giá. Null với hợp đồng tùy chỉnh; không bao giờ suy ra giá thị trường từ mã token. Chỉ metadata CoinGecko không bao giờ khiến token có thể được chọn.
custom_tokenbooleanluôn luônHợp đồng tùy chỉnh đã xác minh trên chuỗi với định giá USD cố định hoặc pool DEX được chọn theo phạm vi dự án.
token_standarderc20 | spl-token | nullluôn luônTiêu chuẩn token đã xác minh dùng lúc chạy; null với tài sản gốc.
metadata_verified_attimestamp | nullluôn luônThời điểm xác minh metadata trên chuỗi cho token được đưa vào sử dụng.
payment_supportedbooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
scanner_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
balance_readybooleanluôn luônĐiều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.Chi tiết
Điều kiện sổ đăng ký tại lúc dựng. scanner_ready nghĩa là thành phần quét thanh toán đã cài; xác nhận thanh toán cần số nhà cung cấp khỏe mạnh đúng vai trò đã cấu hình (mặc định 2, tùy chọn 1); tính khả dụng máy quét tạm thời không chặn tạo hóa đơn từ 6.0.6. balance_ready chỉ true với adapter số dư đã được triển khai.
default_finality_modeconfirmations | finalizedluôn luônMô hình hoàn tất mặc định được chính sách dự án mới kế thừa.
project_policyobject | nullluôn luôn
Chính sách dự án cha.
finality_modeconfirmations | finalizedbắt buộcChính sách hoàn tất được hệ thống tài sản hỗ trợ. finalized cần required_confirmations=1.
required_confirmationsintegerbắt buộcHệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.Chi tiết
Hệ thống Bitcoin và EVM chấp nhận không xác nhận; hệ thống xác nhận khác cần ít nhất một, hệ thống chỉ finalized cần đúng một, còn EVM giới hạn 0–48 để mọi khoản chuyển vẫn trong cửa sổ phát lại giao dịch.
selectedbooleanluôn luônPhương thức này có thuộc cấu hình mong muốn đã lưu của cửa hàng hay không. Nó được cung cấp khi chính sách dự án, ví, adapter đã cài và định giá hợp lệ. Sự cố máy quét tạm thời không loại nó khỏi hóa đơn mới.Chi tiết
Phương thức này có thuộc cấu hình mong muốn đã lưu của cửa hàng hay không. Nó được cung cấp khi chính sách dự án, ví, adapter đã cài và định giá hợp lệ. Sự cố máy quét tạm thời không loại nó khỏi hóa đơn mới.
confirmation_policyobject | nullluôn luôn
Chính sách cửa hàng có hiệu lực cho tài sản đã cấu hình trong dự án. Null khi không có chính sách dự án.
finality_modeconfirmations | finalizedluôn luônQuyết toán dùng số khối có thể cấu hình hay tính hoàn tất mạng.
project_required_confirmationsintegerluôn luônMặc định dự án hiện tại dùng cho hóa đơn tương lai khi không đặt ghi đè cửa hàng.
override_required_confirmationsinteger | nullluôn luônSố riêng cho cửa hàng hoặc null để kế thừa mặc định dự án.
effective_required_confirmationsintegerluôn luônSố mà hóa đơn mới cho cửa hàng và tài sản này sẽ chụp lưu.
minimum_required_confirmationsintegerluôn luônCận dưới bao gồm giá trị biên theo chuỗi; chỉ cung cấp 0 trên hệ thống hỗ trợ chấp nhận ngay khi phát hiện.
walletobject | nullluôn luôn
Ví chuỗi dùng chung cho tài sản gốc và token.
backup_confirmed_attimestamp | nullluôn luônKhác null sau khi nhà vận hành xác nhận sao lưu khôi phục.
activation_requiredbooleanluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
activation_verified_attimestamp|nullluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
receive_readinessobject | null5.5.0+
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.Chi tiết
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
monero_wallet_rpcMoneroWalletRpcBinding | nullluôn luônTrạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.Chi tiết
Trạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.
last_secret_revealed_attimestamp|nullluôn luônMetadata kiểm toán việc hiển thị bí mật phía bảng điều khiển.
balances[]object[]luôn luôn
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.Chi tiết
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.
active_store_countintegerluôn luônSố cửa hàng đang bật hiện chọn tài sản này. Đây là dữ liệu thể hiện việc chấp nhận; theo dõi số dư chỉ đọc vẫn độc lập.
active_store_ids[]UUID[]luôn luônCửa hàng đang bật trong dự án này hiện chấp nhận tài sản. Cho phép lọc cửa hàng cục bộ chính xác mà không cần yêu cầu API khác.
tracking_activebooleanluôn luônVí có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.Chi tiết
Ví có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.
balancedecimal string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
balance_atomicinteger string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
statuspending | refreshing | fresh | stale | errorluôn luônTrạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.Chi tiết
Trạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.
balance_statuspending | refreshing | fresh | stale | error | unknownluôn luônĐộ mới bộ nhớ đệm tổng hợp; unknown là giá trị dự phòng an toàn và không trạng thái nào chứng minh quyết toán hóa đơn.
balance_checked_attimestamp | nullluôn luônLần kiểm tra số dư thành công liên quan cũ nhất được thể hiện trong tổng hợp.
recent_payments[]object[]luôn luôn
Tối đa ba quan sát hợp lệ mới nhất ở trạng thái detected, confirming hoặc final được gán cho đúng ví này.
statusdetected | confirming | finalluôn luônTrạng thái quan sát hợp lệ hiện tại. Loại trừ quan sát reorged, replaced và invalid.
wallet_readinessreadiness enumluôn luônChỉ trạng thái ví/chính sách; dùng receive_readiness cho điều kiện tiên quyết máy quét.
receive_readinessobject | null5.5.0+
Thiết lập nhận tiền dùng chung cộng việc chấp nhận của cửa hàng. Dùng quan sát lưu đệm; không giữ chỗ hay bảo đảm. Tạo hóa đơn kiểm tra lại điều kiện và tỷ giá hóa đơn thực tế.Chi tiết
Thiết lập nhận tiền dùng chung cộng việc chấp nhận của cửa hàng. Dùng quan sát lưu đệm; không giữ chỗ hay bảo đảm. Tạo hóa đơn kiểm tra lại điều kiện và tỷ giá hóa đơn thực tế.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
Ghi chú sử dụng
- Dùng {"strategy":"inherit"} để bỏ ghi đè cửa hàng và theo mặc định dự án hiện tại cho hóa đơn tương lai.
- Mạng finalized trả editable false và dùng tính hoàn tất mạng; không chấp nhận ghi đè số khối tùy chỉnh.
- Giá trị 0 nghĩa là chấp nhận khi phát hiện, không xác nhận mạng và không bảo vệ khỏi tái tổ chức chuỗi. Chỉ chấp nhận nơi minimum_required_confirmations là 0.
- Thay đổi chính sách chỉ ảnh hưởng hóa đơn mới. Hóa đơn hiện có giữ bản chụp chính sách xác nhận dự án/cửa hàng được ghi lúc tạo.
- Cập nhật từng tài sản một; tuần tự hóa chỉnh sửa đồng thời cho cùng tài sản cửa hàng và dùng phản hồi đã làm mới làm trạng thái hiện tại.
Lỗi
GETLiệt kê ví và số dư của dự án/v1/projects/{project_id}/walletsChỉ đọc
Trả metadata ví công khai cộng mọi tài sản đã đăng ký có khả năng đọc số dư trên đúng chuỗi và mạng của ví. Bao phủ cả 30 hệ thống chuỗi gốc; cũng theo dõi tài sản ERC-20 và SPL đã xác minh. Tài sản xuất hiện ngay, kể cả trước lần quét đầu hoặc khi không được chấp nhận thanh toán. project_enabled báo việc chấp nhận thanh toán; tracking_active độc lập báo đủ điều kiện làm mới chỉ đọc. Monero cần wallet-RPC chỉ xem bên ngoài gắn với dự án. Quét số dư trong bảng điều khiển ưu tiên lượt đọc có giới hạn với tiến độ/lỗi theo tài sản; chỉ chu kỳ hoàn chỉnh cập nhật tổng mới. Quyết toán hóa đơn vẫn do theo dõi cấp giao dịch và chính sách xác nhận quyết định, không phải số dư lưu đệm này.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/wallets" \
--header "Authorization: Bearer $WHOLLY_TOKEN"// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/wallets", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/wallets");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$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
headers = {}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/wallets",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [
{
"id": "55555555-5555-4555-8555-555555555555",
"project_id": "11111111-1111-4111-8111-111111111111",
"native_asset_id": "10000000-0000-4000-8000-000000000003",
"chain_slug": "ethereum",
"network": "mainnet",
"asset_symbol": "ETH",
"asset_name": "Ethereum",
"status": "active",
"label": "Primary Ethereum wallet",
"public_key": "0x…",
"primary_address": "0x…",
"derivation_scheme": "bip44",
"address_format": "eip55",
"backup_confirmed_at": "2026-08-31T17:00:00Z",
"last_secret_revealed_at": null,
"secret_reveal_count": 0,
"next_receive_index": 43,
"last_scanned_height": 23123456,
"last_scanned_at": "2026-08-31T18:05:00Z",
"last_error": null,
"balances": [
{ "wallet_id": "55555555-5555-4555-8555-555555555555", "asset_id": "10000000-0000-4000-8000-000000000003", "project_enabled": true, "tracking_active": true, "asset_kind": "native", "contract_address": null, "symbol": "ETH", "name": "Ethereum", "decimals": 18, "coingecko_id": "ethereum", "balance": "0.125", "balance_atomic": "125000000000000000", "price_usd": "4500", "value_usd": "562.50", "status": "fresh", "checked_at": "2026-08-31T18:05:00Z", "last_error": null },
{ "wallet_id": "55555555-5555-4555-8555-555555555555", "asset_id": "10000000-0000-4000-8000-000000000099", "project_enabled": false, "tracking_active": true, "asset_kind": "token", "contract_address": "0xA0b86991c6218b36c1d19d4a2e9eb0cE3606eB48", "symbol": "USDC", "name": "USDC", "decimals": 6, "coingecko_id": "usd-coin", "balance": null, "balance_atomic": null, "price_usd": "1", "value_usd": null, "status": "pending", "checked_at": null, "last_error": null }
],
"total_value_usd": "562.50",
"balance_status": "fresh",
"balance_checked_at": "2026-08-31T18:05:00Z",
"recent_payments": [
{ "invoice_public_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50", "chain_slug": "ethereum", "symbol": "USDC", "transaction_id": "0x…", "event_index": 0, "amount": "25", "status": "final", "confirmations": 12, "observed_at": "2026-08-31T18:04:00Z" }
],
"created_at": "2026-08-31T16:00:00Z",
"updated_at": "2026-08-31T18:05:00Z"
}
]
}Trường phản hồi
data[]object[]
backup_confirmed_attimestamp | nullluôn luônKhác null sau khi nhà vận hành xác nhận sao lưu khôi phục.
activation_requiredbooleanluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
activation_verified_attimestamp|nullluôn luônTài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.Chi tiết
Tài khoản dùng chung XRP và Stellar không khả dụng cho đến khi nhà vận hành nạp địa chỉ được hiển thị và nhà cung cấp máy quét đã cấu hình xác minh đúng tài khoản đó. Bằng chứng bền vững không hết hạn; tình trạng máy quét trực tiếp được kiểm tra riêng khi xác minh thanh toán, không phải khi tạo hóa đơn.
receive_readinessobject | null5.5.0+
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.Chi tiết
Có trong danh sách ví: thiết lập nhận tiền dự án và điều kiện tiên quyết máy quét chuỗi. Tách biệt với số dư, gas token và khả năng gửi. Phản hồi ví khác có thể để null.
readybooleanluôn luônKiểm tra thiết lập nhận tiền đạt yêu cầu. Không mô tả khả năng chi tiêu, gas, làm mới số dư hay bảo đảm báo giá tương lai.
invoice_creatableboolean6.0.6+Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.Chi tiết
Cấu hình cho phép phương thức hóa đơn dù máy quét có cảnh báo tạm thời. Giá tiền tệ được kiểm tra lúc tạo. Đây không phải xác minh thanh toán: ready có thể false khi invoice_creatable true. Thiếu ví, chính sách tắt và adapter không hỗ trợ vẫn bị từ chối an toàn.
issues[]object[]luôn luôn
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.Chi tiết
Rỗng khi sẵn sàng; nếu không là cảnh báo nhận tiền hoặc cấu hình chặn. Kiểm tra invoice_creatable để phân biệt cảnh báo máy quét tạm thời với lỗi thiết lập hóa đơn.
reason_codestringluôn luônscanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.Chi tiết
scanner_provider_quorum, scanner_not_checked, scanner_unavailable, wallet_missing, wallet_disabled, wallet_backup_required, wallet_key_unavailable, wallet_activation_required, monero_binding_unavailable, rate_unavailable, custom_rate_unavailable, lightning_unavailable, project_disabled, store_disabled, chain_disabled, asset_disabled hoặc asset_not_accepted.
messagestringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
actionstringkhi cóGiải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.Chi tiết
Giải thích cho nhà bán hàng và mã hành động: chain_connections, wallets, rates, payment_methods, project_settings hoặc store_settings. Không có thông tin xác thực hay URL nhà cung cấp riêng.
required_endpoint_rolestring | nulltrên chuỗiVai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.Chi tiết
Vai trò API máy quét ưu tiên (trường cũ). Dùng accepted_endpoint_roles cho danh sách tương thích đầy đủ. Tình trạng nút cơ bản không chứng minh hỗ trợ lịch sử thanh toán.
accepted_endpoint_roles[]string[] | nulltrên chuỗiCác biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.Chi tiết
Các biến thể API tương thích, không phải bằng chứng về lịch sử hay năng lực endpoint. node-rpc thô hỗ trợ BTC/BCH/LTC/DOGE/DASH và ZEC minh bạch (khối giải mã đầy đủ, 1–48 xác nhận), TRX gốc đã solidified, ALGO gốc qua algod, XTZ qua Octez, DOT Asset Hub finalized qua metadata SCALE và XLM gốc qua Stellar RPC với memo ID hóa đơn. Lịch sử bị cắt tỉa hoặc thiếu không đủ điều kiện. Các adapter thô này không thêm hệ thống token. API lập chỉ mục vẫn là lựa chọn thay thế; xem bảng hệ thống bên dưới. Nguồn thô/lập chỉ mục kết hợp xác minh cửa sổ giới hạn độc lập; mặc định vẫn là hai nhà cung cấp độc lập, không phải bí danh của cùng nhà vận hành. Độ cao nút cơ bản, thông tin chuỗi ORDnet và relay EVM cho hệ thống không phải EVM không phải bằng chứng nhận tiền. Monero vẫn cần wallet-RPC chỉ xem gắn với dự án.
usable_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
required_independent_providersintegertrên chuỗiSố vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.Chi tiết
Số vị trí xác minh dùng được, tối đa hai. required_independent_providers là cài đặt chuỗi: mặc định 2, hoặc 1 sau khi quản trị viên chủ động chọn. Trong chế độ hai nhà cung cấp, cần khác cả khóa nhà cung cấp VÀ máy chủ. Nguồn bị tắt, cũ (quá mười phút) hoặc đang chờ hạn mức không lấp vị trí. Lightning dùng quy tắc kết nối riêng.
last_checked_attimestamp | nulltrên chuỗiLần kiểm tra tình trạng endpoint khớp mới nhất, tách biệt thời điểm đánh giá.
monero_wallet_rpcMoneroWalletRpcBinding | nullluôn luônTrạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.Chi tiết
Trạng thái liên kết wallet-RPC chỉ xem bên ngoài của Monero đã lọc dữ liệu nhạy cảm. Gồm endpoint, chế độ xác thực, địa chỉ chính account-0, cờ/độ cao bằng chứng kỹ thuật và dấu thời gian xác nhận của nhà vận hành; thông tin xác thực, khóa ví và tệp ví không bao giờ được tuần tự hóa.
last_secret_revealed_attimestamp|nullluôn luônMetadata kiểm toán việc hiển thị bí mật phía bảng điều khiển.
balances[]object[]luôn luôn
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.Chi tiết
Số dư lưu đệm cho từng hệ thống trong 30 chuỗi gốc, cộng tài sản ERC-20 và SPL đã xác minh. Monero cần wallet-RPC chỉ xem bên ngoài đã cấu hình.
active_store_countintegerluôn luônSố cửa hàng đang bật hiện chọn tài sản này. Đây là dữ liệu thể hiện việc chấp nhận; theo dõi số dư chỉ đọc vẫn độc lập.
active_store_ids[]UUID[]luôn luônCửa hàng đang bật trong dự án này hiện chấp nhận tài sản. Cho phép lọc cửa hàng cục bộ chính xác mà không cần yêu cầu API khác.
tracking_activebooleanluôn luônVí có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.Chi tiết
Ví có khả năng đọc và tài sản cùng chuỗi đã đăng ký này có đủ điều kiện làm mới số dư nền hay không. Công tắc chấp nhận của dự án và phương thức thanh toán không tạm dừng theo dõi chỉ đọc.
balancedecimal string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
balance_atomicinteger string|nullluôn luônSố dư hiển thị và theo đơn vị nhỏ nhất chính xác trên địa chỉ chính ví cùng địa chỉ hóa đơn đã cấp. Null khi chưa có giá trị đầy đủ.
statuspending | refreshing | fresh | stale | errorluôn luônTrạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.Chi tiết
Trạng thái quét lưu đệm. refreshing có thể giữ số dư đã hoàn tất: dùng checked_at để biết độ cũ. Pending nghĩa là chưa có bản chụp hoàn tất. Không trạng thái nào chứng minh chuyển tiền đang chờ hay hóa đơn đã quyết toán.
balance_statuspending | refreshing | fresh | stale | error | unknownluôn luônĐộ mới bộ nhớ đệm tổng hợp; unknown là giá trị dự phòng an toàn và không trạng thái nào chứng minh quyết toán hóa đơn.
balance_checked_attimestamp | nullluôn luônLần kiểm tra số dư thành công liên quan cũ nhất được thể hiện trong tổng hợp.
recent_payments[]object[]luôn luôn
Tối đa ba quan sát hợp lệ mới nhất ở trạng thái detected, confirming hoặc final được gán cho đúng ví này.
statusdetected | confirming | finalluôn luônTrạng thái quan sát hợp lệ hiện tại. Loại trừ quan sát reorged, replaced và invalid.
Ghi chú sử dụng
- Tuyến bearer này không bao giờ trả cụm từ khôi phục, khóa riêng, bí mật mã hóa hay phương thức chi tiêu.
- Tài sản cùng chuỗi mới đăng ký được trả với số dư null và trạng thái pending trước lần quét hoàn tất đầu tiên; không bao giờ báo số không giả.
- Tắt dự án, ví nhận thanh toán, hệ thống đồng gốc hoặc từng tài sản không dừng theo dõi số dư chỉ đọc: ví hoạt động và bị tắt có địa chỉ chính tiếp tục làm mới mọi tài sản cùng chuỗi đã đăng ký, được hỗ trợ. Ví pending và error không được quét.
- project_enabled chỉ báo chính sách chấp nhận tài sản của dự án và có thể false trong khi tracking_active vẫn true.
- balance và balance_atomic là chuỗi chính xác; price_usd, value_usd và total_value_usd chỉ để tham khảo và có thể null. Trạng thái số dư mới không bảo đảm giá thị trường mới.
- Định giá ưu tiên giá CoinGecko cũ tối đa hai giờ. Đồng gốc và USDC/USDT chính tắc đã xác minh có thể dùng dự phòng báo giá USD Kraken/Binance đang bật cũ tối đa năm phút, nhà cung cấp chính trước. Không giả định neo giá đô la hay định giá token tùy chỉnh chỉ theo mã; giá cố định/DEX của dự án giữ riêng. Báo giá hóa đơn không đổi.
- Pending chưa có bản chụp hoàn chỉnh. Refreshing giữ số tiền hoàn tất và checked_at cuối; không có nghĩa giao dịch blockchain đang chờ. Số tiền stale/error cũng có thể giữ giá trị cũ. Không bao giờ coi bộ nhớ đệm không khả dụng là số không hay thiếu thanh toán. Làm mới EVM/Solana định kỳ dùng lại địa chỉ rỗng mới kiểm tra tối đa 30 phút giữa các lần kiểm tra đầy đủ, còn địa chỉ có tiền, mới và thay đổi được kiểm tra lại. Lệnh Quét số dư rõ ràng trong bảng điều khiển yêu cầu quét toàn bộ.
- recent_payments giới hạn ba quan sát mỗi ví và loại trừ lịch sử đã vô hiệu hóa.
Lỗi
POSTTạo hóa đơn/v1/projects/{project_id}/stores/{store_id}/invoicesĐọc + ghi
Tạo hóa đơn nguyên tử cùng đích ví, báo giá mới chính xác, lịch sử kiểm toán và mục hộp gửi thông báo. Phát lại byte nội dung thô giống hệt bằng cùng thông tin xác thực và Idempotency-Key trả hóa đơn gốc.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Idempotency-Key | bắt buộc | 1–128 ký tự ASCII hiển thị duy nhất, không khoảng trắng. |
| Content-Type | khuyến nghị | application/json. Trình xử lý nội dung thô hiện tại phân tích JSON mà không bắt buộc loại phương tiện. |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
project_idUUIDbắt buộcSao chép ID API dự án từ Dự án → Cài đặt → ID API. Phải được gán cho thông tin xác thực; không chấp nhận mã định danh dự án dễ đọc.
store_idUUIDbắt buộcSao chép ID API cửa hàng từ Dự án → Cửa hàng → chọn cửa hàng → Cơ bản → ID API. Bắt buộc kể cả cửa hàng mặc định; phải đang bật và thuộc project_id.
Yêu cầu
: "${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": "49.90",
"currency": "USD"
}'// 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": "49.90",
"currency": "USD"
}`;
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": "49.90",
"currency": "USD"
}
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": "49.90",
"currency": "USD"
}""".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)): "${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 '{
"payment_methods": [
{
"chain_slug": "bitcoin",
"asset_tickers": [
"BTC"
]
}
],
"amount": "49.90",
"currency": "USD",
"order_id": "order-1042",
"email": "ada@example.com",
"description": "Annual plan",
"underpayment_tolerance_percent": "1",
"ipn_url": "https://merchant.example/wholly/ipn",
"redirect_url": "https://merchant.example/orders/1042",
"cancel_url": "https://merchant.example/cart",
"redirect_automatically": true,
"language": "en",
"metadata": {
"cart_id": "cart-681",
"firstname": "Ada",
"lastname": "Lovelace",
"street": "12 Example Street",
"street2": "Suite 2",
"zip": "10115",
"city": "Berlin",
"country": "Germany",
"countryiso2": "DE",
"company": "Example GmbH",
"vatid": "DE123456789"
},
"exchange_rate_spread_percent": "0.5",
"checkout_appearance": {
"title": "Complete your order",
"intro": "Thanks for choosing our annual plan.",
"outro": "Questions? https://merchant.example/help",
"intro_font_size": 18,
"outro_font_size": 14,
"theme": "light",
"accent_color": "#1768CE",
"messages": {
"en": {
"paid": "Your order is ready."
}
}
}
}'// 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 = `{
"payment_methods": [
{
"chain_slug": "bitcoin",
"asset_tickers": [
"BTC"
]
}
],
"amount": "49.90",
"currency": "USD",
"order_id": "order-1042",
"email": "ada@example.com",
"description": "Annual plan",
"underpayment_tolerance_percent": "1",
"ipn_url": "https://merchant.example/wholly/ipn",
"redirect_url": "https://merchant.example/orders/1042",
"cancel_url": "https://merchant.example/cart",
"redirect_automatically": true,
"language": "en",
"metadata": {
"cart_id": "cart-681",
"firstname": "Ada",
"lastname": "Lovelace",
"street": "12 Example Street",
"street2": "Suite 2",
"zip": "10115",
"city": "Berlin",
"country": "Germany",
"countryiso2": "DE",
"company": "Example GmbH",
"vatid": "DE123456789"
},
"exchange_rate_spread_percent": "0.5",
"checkout_appearance": {
"title": "Complete your order",
"intro": "Thanks for choosing our annual plan.",
"outro": "Questions? https://merchant.example/help",
"intro_font_size": 18,
"outro_font_size": 14,
"theme": "light",
"accent_color": "#1768CE",
"messages": {
"en": {
"paid": "Your order is ready."
}
}
}
}`;
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'
{
"payment_methods": [
{
"chain_slug": "bitcoin",
"asset_tickers": [
"BTC"
]
}
],
"amount": "49.90",
"currency": "USD",
"order_id": "order-1042",
"email": "ada@example.com",
"description": "Annual plan",
"underpayment_tolerance_percent": "1",
"ipn_url": "https://merchant.example/wholly/ipn",
"redirect_url": "https://merchant.example/orders/1042",
"cancel_url": "https://merchant.example/cart",
"redirect_automatically": true,
"language": "en",
"metadata": {
"cart_id": "cart-681",
"firstname": "Ada",
"lastname": "Lovelace",
"street": "12 Example Street",
"street2": "Suite 2",
"zip": "10115",
"city": "Berlin",
"country": "Germany",
"countryiso2": "DE",
"company": "Example GmbH",
"vatid": "DE123456789"
},
"exchange_rate_spread_percent": "0.5",
"checkout_appearance": {
"title": "Complete your order",
"intro": "Thanks for choosing our annual plan.",
"outro": "Questions? https://merchant.example/help",
"intro_font_size": 18,
"outro_font_size": 14,
"theme": "light",
"accent_color": "#1768CE",
"messages": {
"en": {
"paid": "Your order is ready."
}
}
}
}
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 = """{
"payment_methods": [
{
"chain_slug": "bitcoin",
"asset_tickers": [
"BTC"
]
}
],
"amount": "49.90",
"currency": "USD",
"order_id": "order-1042",
"email": "ada@example.com",
"description": "Annual plan",
"underpayment_tolerance_percent": "1",
"ipn_url": "https://merchant.example/wholly/ipn",
"redirect_url": "https://merchant.example/orders/1042",
"cancel_url": "https://merchant.example/cart",
"redirect_automatically": true,
"language": "en",
"metadata": {
"cart_id": "cart-681",
"firstname": "Ada",
"lastname": "Lovelace",
"street": "12 Example Street",
"street2": "Suite 2",
"zip": "10115",
"city": "Berlin",
"country": "Germany",
"countryiso2": "DE",
"company": "Example GmbH",
"vatid": "DE123456789"
},
"exchange_rate_spread_percent": "0.5",
"checkout_appearance": {
"title": "Complete your order",
"intro": "Thanks for choosing our annual plan.",
"outro": "Questions? https://merchant.example/help",
"intro_font_size": 18,
"outro_font_size": 14,
"theme": "light",
"accent_color": "#1768CE",
"messages": {
"en": {
"paid": "Your order is ready."
}
}
}
}""".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))Nội dung yêu cầu
amountstringbắt buộcChuỗi thập phân thuần không dấu; không dấu hay số mũ, tối đa 48 chữ số nguyên và 30 chữ số thập phân. Mặc định phải dương. Cửa hàng có thể cho phép hóa đơn số tiền bằng không trong Cửa hàng → Hóa đơn; tổng bằng không được quyết toán mà không nhận tiền, cấp địa chỉ hay tính phí xử lý.Chi tiết
Chuỗi thập phân thuần không dấu; không dấu hay số mũ, tối đa 48 chữ số nguyên và 30 chữ số thập phân. Mặc định phải dương. Cửa hàng có thể cho phép hóa đơn số tiền bằng không trong Cửa hàng → Hóa đơn; tổng bằng không được quyết toán mà không nhận tiền, cấp địa chỉ hay tính phí xử lý.
currencystring | nulltùy chọnTiền pháp định ba chữ cái được hỗ trợ, chuẩn hóa thành chữ hoa. Bỏ qua hoặc null kế thừa tiền hóa đơn của cửa hàng. Tạo hóa đơn cũng cần tỷ giá quy đổi tính phí độc lập có sẵn.Chi tiết
Tiền pháp định ba chữ cái được hỗ trợ, chuẩn hóa thành chữ hoa. Bỏ qua hoặc null kế thừa tiền hóa đơn của cửa hàng. Tạo hóa đơn cũng cần tỷ giá quy đổi tính phí độc lập có sẵn.
payment_methods[]object[] | nulltùy chọn
Chọn phương thức đang bật của cửa hàng cho hóa đơn này. Merchant 5.4.0+: bỏ qua lựa chọn không xác định/không hoạt động/không được chấp nhận; nếu không khớp lựa chọn nào, dùng mặc định cửa hàng. Bỏ qua/null cũng dùng mặc định cửa hàng; [] không hợp lệ. Không bao giờ bật phương thức hay đổi cài đặt cửa hàng. Xem lược đồ lựa chọn bên dưới.Chi tiết
Chọn phương thức đang bật của cửa hàng cho hóa đơn này. Merchant 5.4.0+: bỏ qua lựa chọn không xác định/không hoạt động/không được chấp nhận; nếu không khớp lựa chọn nào, dùng mặc định cửa hàng. Bỏ qua/null cũng dùng mặc định cửa hàng; [] không hợp lệ. Không bao giờ bật phương thức hay đổi cài đặt cửa hàng. Xem lược đồ lựa chọn bên dưới.
chain_slugstringbắt buộcSao chép chain_slug trong Dự án → Cửa hàng → Phương thức thanh toán, hoặc đọc từ GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, như ethereum, base hoặc bitcoin. Mỗi cặp chuỗi/hệ thống thanh toán chỉ được xuất hiện một lần.Chi tiết
Sao chép chain_slug trong Dự án → Cửa hàng → Phương thức thanh toán, hoặc đọc từ GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, như ethereum, base hoặc bitcoin. Mỗi cặp chuỗi/hệ thống thanh toán chỉ được xuất hiện một lần.
asset_ids[]UUID[] | nulltùy chọnUUID asset.id trên chuỗi, không phải địa chỉ hợp đồng hay ID phương thức thanh toán hóa đơn. Dùng trường này HOẶC asset_tickers. Bỏ cả hai bộ chọn để lấy mọi tài sản đang hoạt động được chấp nhận trên chuỗi này. [] và ID trùng/rỗng không hợp lệ. Trên 5.4.0+, bỏ qua ID không hoạt động/không được chấp nhận trên chuỗi này trong cửa hàng này; lựa chọn hoàn toàn không khớp sẽ dùng mặc định cửa hàng.Chi tiết
UUID asset.id trên chuỗi, không phải địa chỉ hợp đồng hay ID phương thức thanh toán hóa đơn. Dùng trường này HOẶC asset_tickers. Bỏ cả hai bộ chọn để lấy mọi tài sản đang hoạt động được chấp nhận trên chuỗi này. [] và ID trùng/rỗng không hợp lệ. Trên 5.4.0+, bỏ qua ID không hoạt động/không được chấp nhận trên chuỗi này trong cửa hàng này; lựa chọn hoàn toàn không khớp sẽ dùng mặc định cửa hàng.
asset_tickers[]string[] | nulltùy chọnMerchant 5.3.0+. Ký hiệu như BTC, USDC hoặc PEPE, giới hạn theo chain_slug và cửa hàng này. 1–64 mã duy nhất; bỏ khoảng trắng hai đầu/không phân biệt hoa thường, 1–40 chữ ASCII/số/dấu chấm/gạch dưới/gạch nối. Dùng trường này HOẶC asset_ids. Trên 5.4.0+, bỏ qua mã không xác định/không hoạt động/không được chấp nhận. Ký hiệu được chấp nhận nhưng mơ hồ vẫn gây lỗi: dùng asset_ids. Phương thức đang hoạt động được chọn cần ví và định giá hợp lệ; sự cố máy quét trên chuỗi tạm thời không chặn tạo hóa đơn từ 6.0.6. Lightning tùy chọn chỉ chấp nhận BTC.Chi tiết
Merchant 5.3.0+. Ký hiệu như BTC, USDC hoặc PEPE, giới hạn theo chain_slug và cửa hàng này. 1–64 mã duy nhất; bỏ khoảng trắng hai đầu/không phân biệt hoa thường, 1–40 chữ ASCII/số/dấu chấm/gạch dưới/gạch nối. Dùng trường này HOẶC asset_ids. Trên 5.4.0+, bỏ qua mã không xác định/không hoạt động/không được chấp nhận. Ký hiệu được chấp nhận nhưng mơ hồ vẫn gây lỗi: dùng asset_ids. Phương thức đang hoạt động được chọn cần ví và định giá hợp lệ; sự cố máy quét trên chuỗi tạm thời không chặn tạo hóa đơn từ 6.0.6. Lightning tùy chọn chỉ chấp nhận BTC.
payment_railonchain | lightningtùy chọnMặc định onchain. Để chọn Bitcoin Lightning, dùng {chain_slug: bitcoin, payment_rail: lightning} không có asset_ids; asset_tickers có thể tùy chọn là [BTC]. Bitcoin trên chuỗi không bao gồm Lightning. Kết nối Lightning của cửa hàng phải được bật và sẵn sàng từ trước.Chi tiết
Mặc định onchain. Để chọn Bitcoin Lightning, dùng {chain_slug: bitcoin, payment_rail: lightning} không có asset_ids; asset_tickers có thể tùy chọn là [BTC]. Bitcoin trên chuỗi không bao gồm Lightning. Kết nối Lightning của cửa hàng phải được bật và sẵn sàng từ trước.
order_idstring | nulltùy chọnMã tham chiếu đơn hàng của nhà bán hàng, 1–128 ký tự sau khi bỏ khoảng trắng hai đầu; từ chối ký tự điều khiển.
emailstring | nulltùy chọnEmail khách hàng chỉ dành cho nhà bán hàng, chuẩn hóa thành địa chỉ ASCII thực tế tối đa 254 ký tự. Bỏ qua hoặc null sẽ không lưu email.
descriptionstring | nulltùy chọnMô tả hiển thị cho khách hàng, 1–500 ký tự; cho phép xuống dòng và tab.
expires_in_secondsinteger | nulltùy chọnThời hạn báo giá hóa đơn từ 300 đến 86,400 giây; bỏ qua hoặc null kế thừa chính sách cửa hàng.
exchange_rate_spread_percentdecimal string | nulltùy chọnPhần cộng giá từ 0 đến 100, tối đa hai chữ số thập phân. Bỏ qua hoặc null kế thừa mặc định cửa hàng; "0" tắt cho hóa đơn này. Áp dụng trước làm tròn lên, rồi khóa lại. Không đổi số tiền pháp định hóa đơn hay cơ sở phí xử lý.Chi tiết
Phần cộng giá từ 0 đến 100, tối đa hai chữ số thập phân. Bỏ qua hoặc null kế thừa mặc định cửa hàng; "0" tắt cho hóa đơn này. Áp dụng trước làm tròn lên, rồi khóa lại. Không đổi số tiền pháp định hóa đơn hay cơ sở phí xử lý.
underpayment_tolerance_percentdecimal string | nulltùy chọnPhần thiếu được chấp nhận từ 0 đến 99.99, tối đa hai chữ số thập phân. Bỏ qua hoặc null kế thừa mặc định cửa hàng.
ipn_urlstring | nulltùy chọnCallback HTTPS công khai, tối đa 2,048 byte, không có thông tin xác thực hay fragment. Ghi đè mặc định cửa hàng; null/bỏ qua kế thừa nó.
redirect_urlstring | nulltùy chọnURL thành công HTTPS dùng sau quyết toán, tối đa 2,048 byte, không nhúng thông tin xác thực. Bỏ qua hoặc null kế thừa mặc định cửa hàng và không thể xóa nó.
cancel_urlstring | nulltùy chọnURL trả về HTTPS dùng khi thanh toán kết thúc mà chưa thành công. Bỏ qua hoặc null kế thừa mặc định cửa hàng và không thể xóa nó.
redirect_automaticallyboolean | nulltùy chọnBỏ qua hoặc null kế thừa chính sách cửa hàng. true cần redirect_url có hiệu lực.
languagestring | nulltùy chọnNgôn ngữ khách hàng: en, de, es, pt-BR, it, ru, zh-CN, fr, ko hoặc ja. pt nghĩa là tiếng Bồ Đào Nha Brazil và zh nghĩa là tiếng Trung giản thể. Thẻ khu vực được hỗ trợ như de-DE được chuẩn hóa về ngôn ngữ trong danh sách. Bỏ qua hoặc null kế thừa ngôn ngữ cửa hàng. Ngôn ngữ bảng điều khiển tách biệt.Chi tiết
Ngôn ngữ khách hàng: en, de, es, pt-BR, it, ru, zh-CN, fr, ko hoặc ja. pt nghĩa là tiếng Bồ Đào Nha Brazil và zh nghĩa là tiếng Trung giản thể. Thẻ khu vực được hỗ trợ như de-DE được chuẩn hóa về ngôn ngữ trong danh sách. Bỏ qua hoặc null kế thừa ngôn ngữ cửa hàng. Ngôn ngữ bảng điều khiển tách biệt.
checkout_appearanceobject | nulltùy chọn
Cài đặt trình bày một phần cho hóa đơn này. Bỏ qua/null theo thiết kế hiện tại của cửa hàng. Một đối tượng, kể cả {}, đóng băng thiết kế đã phân giải và hình ảnh lúc tạo. Xem lược đồ ghi đè bên dưới; không có cài đặt tài chính, HTML, CSS, JavaScript hay URL ảnh từ xa.Chi tiết
Cài đặt trình bày một phần cho hóa đơn này. Bỏ qua/null theo thiết kế hiện tại của cửa hàng. Một đối tượng, kể cả {}, đóng băng thiết kế đã phân giải và hình ảnh lúc tạo. Xem lược đồ ghi đè bên dưới; không có cài đặt tài chính, HTML, CSS, JavaScript hay URL ảnh từ xa.
inherit_default_storebooleantùy chọntrue chọn thiết kế cửa hàng mặc định của dự án làm nền; nếu không dùng thiết kế có hiệu lực của cửa hàng đích. Sau đó áp dụng và lưu ghi đè độc lập; cờ hóa đơn sau phân giải là false.Chi tiết
true chọn thiết kế cửa hàng mặc định của dự án làm nền; nếu không dùng thiết kế có hiệu lực của cửa hàng đích. Sau đó áp dụng và lưu ghi đè độc lập; cờ hóa đơn sau phân giải là false.
introstringtùy chọnVăn bản thuần, mỗi mục tối đa 2,000 ký tự. Lời mở ở trên, lời kết ở dưới trong mọi trạng thái. Giữ xuống dòng; URL văn bản an toàn trở thành liên kết. Chuỗi rỗng sẽ xóa. customer_message cũ được chấp nhận làm bí danh cho intro; không gửi cả hai.Chi tiết
Văn bản thuần, mỗi mục tối đa 2,000 ký tự. Lời mở ở trên, lời kết ở dưới trong mọi trạng thái. Giữ xuống dòng; URL văn bản an toàn trở thành liên kết. Chuỗi rỗng sẽ xóa. customer_message cũ được chấp nhận làm bí danh cho intro; không gửi cả hai.
outrostringtùy chọnVăn bản thuần, mỗi mục tối đa 2,000 ký tự. Lời mở ở trên, lời kết ở dưới trong mọi trạng thái. Giữ xuống dòng; URL văn bản an toàn trở thành liên kết. Chuỗi rỗng sẽ xóa. customer_message cũ được chấp nhận làm bí danh cho intro; không gửi cả hai.Chi tiết
Văn bản thuần, mỗi mục tối đa 2,000 ký tự. Lời mở ở trên, lời kết ở dưới trong mọi trạng thái. Giữ xuống dòng; URL văn bản an toàn trở thành liên kết. Chuỗi rỗng sẽ xóa. customer_message cũ được chấp nhận làm bí danh cho intro; không gửi cả hai.
intro_font_sizeintegertùy chọnPixel: 12, 14, 16, 18, 20 hoặc 24. Mặc định 16 nếu không kế thừa giá trị khác.
outro_font_sizeintegertùy chọnPixel: 12, 14, 16, 18, 20 hoặc 24. Mặc định 16 nếu không kế thừa giá trị khác.
accent_colorstringtùy chọn#RRGGBB. Nền, thẻ và nút có thể rỗng để dùng màu tự động. Tương phản chữ tự động.
background_colorstringtùy chọn#RRGGBB. Nền, thẻ và nút có thể rỗng để dùng màu tự động. Tương phản chữ tự động.
card_colorstringtùy chọn#RRGGBB. Nền, thẻ và nút có thể rỗng để dùng màu tự động. Tương phản chữ tự động.
button_colorstringtùy chọn#RRGGBB. Nền, thẻ và nút có thể rỗng để dùng màu tự động. Tương phản chữ tự động.
imagesobjecttùy chọn
Các khóa logo_light, logo_dark, favicon. Bỏ khóa giữ ảnh nền; null xóa ảnh. Đối tượng {store_id: UUID, kind?: logo_light|logo_dark|favicon} dùng lại ảnh tải lên có hiệu lực của cửa hàng đó trong CÙNG dự án. kind mặc định theo khóa đích. Tải lên tại Cửa hàng → Trang thanh toán trước; sao chép ID API cửa hàng từ Cơ bản → ID API. Thiếu ảnh hoặc ID khác dự án trả 400. Không chấp nhận URL ngoài hay dữ liệu ảnh.Chi tiết
Các khóa logo_light, logo_dark, favicon. Bỏ khóa giữ ảnh nền; null xóa ảnh. Đối tượng {store_id: UUID, kind?: logo_light|logo_dark|favicon} dùng lại ảnh tải lên có hiệu lực của cửa hàng đó trong CÙNG dự án. kind mặc định theo khóa đích. Tải lên tại Cửa hàng → Trang thanh toán trước; sao chép ID API cửa hàng từ Cơ bản → ID API. Thiếu ảnh hoặc ID khác dự án trả 400. Không chấp nhận URL ngoài hay dữ liệu ảnh.
show_order_idbooleantùy chọnHiển thị chi tiết ID đơn hàng và mô tả văn bản thuần dưới tiêu đề. details_expanded mở sẵn chi tiết ID đơn hàng. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
show_descriptionbooleantùy chọnHiển thị chi tiết ID đơn hàng và mô tả văn bản thuần dưới tiêu đề. details_expanded mở sẵn chi tiết ID đơn hàng. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
details_expandedbooleantùy chọnHiển thị chi tiết ID đơn hàng và mô tả văn bản thuần dưới tiêu đề. details_expanded mở sẵn chi tiết ID đơn hàng. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
show_project_namebooleantùy chọnMerchant 5.6.0+: hiện hoặc ẩn từng tên trong phần đầu trang thanh toán khách hàng. Cả hai mặc định true. Cũng có tại Cửa hàng → Trang thanh toán; được kế thừa và chụp lưu theo hóa đơn như cài đặt giao diện khác. Chỉ ảnh hưởng hiển thị, không che dữ liệu.Chi tiết
Merchant 5.6.0+: hiện hoặc ẩn từng tên trong phần đầu trang thanh toán khách hàng. Cả hai mặc định true. Cũng có tại Cửa hàng → Trang thanh toán; được kế thừa và chụp lưu theo hóa đơn như cài đặt giao diện khác. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
show_store_namebooleantùy chọnMerchant 5.6.0+: hiện hoặc ẩn từng tên trong phần đầu trang thanh toán khách hàng. Cả hai mặc định true. Cũng có tại Cửa hàng → Trang thanh toán; được kế thừa và chụp lưu theo hóa đơn như cài đặt giao diện khác. Chỉ ảnh hưởng hiển thị, không che dữ liệu.Chi tiết
Merchant 5.6.0+: hiện hoặc ẩn từng tên trong phần đầu trang thanh toán khách hàng. Cả hai mặc định true. Cũng có tại Cửa hàng → Trang thanh toán; được kế thừa và chụp lưu theo hóa đơn như cài đặt giao diện khác. Chỉ ảnh hưởng hiển thị, không che dữ liệu.
featured_chains[]string[]tùy chọnSlug chuỗi có thứ tự, tối đa 60 giá trị duy nhất (chữ thường, số, gạch nối; tối đa 64 ký tự). [] xóa. Chỉ phương thức hóa đơn khả dụng được sắp lại.Chi tiết
Slug chuỗi có thứ tự, tối đa 60 giá trị duy nhất (chữ thường, số, gạch nối; tối đa 64 ký tự). [] xóa. Chỉ phương thức hóa đơn khả dụng được sắp lại.
featured_asset_ids[]UUID[]tùy chọnTối đa 100 ID tài sản duy nhất có thứ tự; [] xóa. Tài sản mặc định có thể null. ID lấy từ payment-assets, không phải ID ý định thanh toán. Chúng không bao giờ bật phương thức; thanh toán đã nhận và tùy chọn khách hàng hợp lệ được ưu tiên.Chi tiết
Tối đa 100 ID tài sản duy nhất có thứ tự; [] xóa. Tài sản mặc định có thể null. ID lấy từ payment-assets, không phải ID ý định thanh toán. Chúng không bao giờ bật phương thức; thanh toán đã nhận và tùy chọn khách hàng hợp lệ được ưu tiên.
default_asset_idUUID|nulltùy chọnTối đa 100 ID tài sản duy nhất có thứ tự; [] xóa. Tài sản mặc định có thể null. ID lấy từ payment-assets, không phải ID ý định thanh toán. Chúng không bao giờ bật phương thức; thanh toán đã nhận và tùy chọn khách hàng hợp lệ được ưu tiên.Chi tiết
Tối đa 100 ID tài sản duy nhất có thứ tự; [] xóa. Tài sản mặc định có thể null. ID lấy từ payment-assets, không phải ID ý định thanh toán. Chúng không bao giờ bật phương thức; thanh toán đã nhận và tùy chọn khách hàng hợp lệ được ưu tiên.
messagesobjecttùy chọn
Đối tượng ngôn ngữ có khóa en, de, es, pt-BR, it, ru, zh-CN, fr, ko hoặc ja, với chuỗi thuần waiting, confirming, paid, underpaid, expired (mỗi chuỗi 500 ký tự). Chỉ ngôn ngữ/trạng thái được cung cấp thay đổi; {} xóa mọi thông báo, {en:{}} xóa tiếng Anh và chuỗi trạng thái rỗng xóa trạng thái đó. Tiếng Anh là dự phòng. Không thay trạng thái thực tế.Chi tiết
Đối tượng ngôn ngữ có khóa en, de, es, pt-BR, it, ru, zh-CN, fr, ko hoặc ja, với chuỗi thuần waiting, confirming, paid, underpaid, expired (mỗi chuỗi 500 ký tự). Chỉ ngôn ngữ/trạng thái được cung cấp thay đổi; {} xóa mọi thông báo, {en:{}} xóa tiếng Anh và chuỗi trạng thái rỗng xóa trạng thái đó. Tiếng Anh là dự phòng. Không thay trạng thái thực tế.
enobjecttùy chọn
deobjecttùy chọn
esobjecttùy chọn
pt-BRobjecttùy chọn
itobjecttùy chọn
ruobjecttùy chọn
zh-CNobjecttùy chọn
frobjecttùy chọn
koobjecttùy chọn
support_urlstringtùy chọnURL HTTPS tối đa 2,048 ký tự, không có thông tin xác thực. Rỗng sẽ xóa. Liên kết mở trong cửa sổ mới.
terms_urlstringtùy chọnURL HTTPS tối đa 2,048 ký tự, không có thông tin xác thực. Rỗng sẽ xóa. Liên kết mở trong cửa sổ mới.
privacy_urlstringtùy chọnURL HTTPS tối đa 2,048 ký tự, không có thông tin xác thực. Rỗng sẽ xóa. Liên kết mở trong cửa sổ mới.
return_button_textstringtùy chọnNhãn tối đa 60 ký tự. Dùng redirect_url/cancel_url/redirect_automatically/language cấp cao nhất cho hành vi hóa đơn.
show_return_buttonbooleantùy chọnHiển thị nút thủ công Quay lại nhà bán hàng/hủy trên trang thanh toán, kể cả trạng thái kết thúc. Bỏ qua để kế thừa giao diện cửa hàng (mặc định true); false ẩn nút. Không hủy hóa đơn, ẩn URL trong JSON hay tắt chuyển hướng thành công tự động. Đặt riêng redirect_automatically cấp cao nhất thành false nếu cần. Yêu cầu merchant 8.1.4 hoặc mới hơn.Chi tiết
Hiển thị nút thủ công Quay lại nhà bán hàng/hủy trên trang thanh toán, kể cả trạng thái kết thúc. Bỏ qua để kế thừa giao diện cửa hàng (mặc định true); false ẩn nút. Không hủy hóa đơn, ẩn URL trong JSON hay tắt chuyển hướng thành công tự động. Đặt riêng redirect_automatically cấp cao nhất thành false nếu cần. Yêu cầu merchant 8.1.4 hoặc mới hơn.
metadataobject | nulltùy chọn
Đối tượng JSON chỉ dành cho nhà bán hàng; bỏ qua hoặc null trở thành {}, tối đa 4,096 byte mã hóa và năm cấp lồng nhau. firstname, lastname, street, street2, zip, city, country, countryiso2, company và vatid được xác thực, chuẩn hóa và đưa vào trường tóm tắt khách hàng.Chi tiết
Đối tượng JSON chỉ dành cho nhà bán hàng; bỏ qua hoặc null trở thành {}, tối đa 4,096 byte mã hóa và năm cấp lồng nhau. firstname, lastname, street, street2, zip, city, country, countryiso2, company và vatid được xác thực, chuẩn hóa và đưa vào trường tóm tắt khách hàng.
Phản hồi 201 new invoice; 200 exact idempotent replay
Phản hồi ví dụ
{
"data": {
"id": "2f798f9f-01f2-42f0-9d10-5581d6116b4c",
"invoice_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50",
"project_id": "11111111-1111-4111-8111-111111111111",
"store_id": "22222222-2222-4222-8222-222222222222",
"source": "api",
"order_id": "order-1042",
"email": "ada@example.com",
"customer_name": "Ada Lovelace · Example GmbH",
"customer_address": "Example GmbH · 12 Example Street · Suite 2 · 10115 Berlin · Germany (DE) · VAT DE123456789",
"description": "Annual plan",
"amount": "49.9",
"currency": "USD",
"exchange_rate_spread_percent": "0.5",
"underpayment_tolerance_percent": "1",
"status": "new",
"amount_status": "none",
"timing_status": "on_time",
"resolution": "automatic",
"sequence": 1,
"winning_payment_intent_id": null,
"expires_at": "2026-08-31T18:15:00Z",
"monitoring_expires_at": "2026-09-07T18:15:00Z",
"settled_at": null,
"cancelled_at": null,
"archived_at": null,
"created_at": "2026-08-31T18:00:00Z",
"updated_at": "2026-08-31T18:00:00Z",
"ipn_url": "https://merchant.example/wholly/ipn",
"redirect_url": "https://merchant.example/orders/1042",
"cancel_url": "https://merchant.example/cart",
"redirect_automatically": true,
"checkout_language": "en",
"metadata": { "cart_id": "cart-681", "firstname": "Ada", "lastname": "Lovelace", "street": "12 Example Street", "street2": "Suite 2", "zip": "10115", "city": "Berlin", "country": "Germany", "countryiso2": "DE", "company": "Example GmbH", "vatid": "DE123456789" },
"payment_intents": [
{
"id": "33333333-3333-4333-8333-333333333333",
"asset_id": "10000000-0000-4000-8000-000000000001",
"asset_key": "bip122:000000000019d6689c085ae165831e93/slip44:0",
"chain_slug": "bitcoin",
"network": "mainnet",
"caip_network_id": "bip122:000000000019d6689c085ae165831e93",
"caip_asset_id": "bip122:000000000019d6689c085ae165831e93/slip44:0",
"symbol": "BTC",
"asset_decimals": 8,
"status": "pending",
"finality_mode": "confirmations",
"required_confirmations": 1,
"quote_rate": "0.000009218",
"quote_details": null,
"expected_amount": "0.00046",
"expected_amount_atomic": "46000",
"minimum_payment_amount": "0.0004554",
"minimum_payment_amount_atomic": "45540",
"received_amount": "0",
"received_amount_atomic": "0",
"confirmed_amount": "0",
"confirmed_amount_atomic": "0",
"destination_address": "bc1q…example",
"destination_tag": null,
"derivation_index": 42,
"quote_expires_at": "2026-08-31T18:15:00Z",
"monitoring_expires_at": "2026-09-07T18:15:00Z",
"next_check_at": "2026-08-31T18:00:00Z",
"last_checked_at": null,
"last_chain_height": null,
"last_anchor_hash": null,
"last_monitor_error": null,
"first_payment_at": null,
"fully_paid_at": null,
"finalized_at": null
}
]
},
"links": {
"checkout": "https://pay.example.com/invoice/0a6a98db-d93d-48ee-8c3c-fd45f90c4a50"
}
}Trường phản hồi
dataobject
idUUIDluôn luônUUID hóa đơn nội bộ. Không dùng trong đường dẫn chi tiết nhà bán hàng hay trang thanh toán.
invoice_idUUIDluôn luônUUID hóa đơn công khai dùng trong đường dẫn chi tiết nhà bán hàng và trang thanh toán.
emailstring | nullluôn luônEmail khách hàng chỉ dành cho nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về.
customer_namestring | nullluôn luônTên hiển thị suy ra từ metadata riêng firstname, lastname và company.
customer_addressstring | nullluôn luônĐịa chỉ một dòng dành cho nhà bán hàng, suy ra từ metadata riêng company, street, street2, zip, city, country, countryiso2 và vatid.
exchange_rate_spread_percentdecimal stringluôn luônChênh lệch báo giá đã khóa: ghi đè lúc tạo hoặc mặc định cửa hàng khi bỏ qua. Áp dụng trước làm tròn lên; không bao giờ thay đổi trên hóa đơn này.
underpayment_tolerance_percentdecimal stringluôn luônTỷ lệ thiếu tiền được chấp nhận bất biến, chụp lưu khi tạo hóa đơn.
amount_statusamount statusluôn luônnone, partial, paid hoặc overpaid. Hóa đơn số tiền bằng không được cho phép rõ ràng sẽ quyết toán với none và không có phương thức thanh toán.
winning_payment_intent_idUUID | nullluôn luônPhương thức thanh toán dùng để xử lý hóa đơn, khi đã chọn.
monitoring_expires_atRFC 3339 timestampluôn luônMốc kết thúc theo dõi muộn được cấu hình xa nhất trong các phương thức thanh toán.
ipn_urlstring | nullluôn luônĐích IPN có hiệu lực theo hóa đơn. Chỉ phản hồi nhà bán hàng; không có trên trang thanh toán công khai.
cancel_urlstring | nullluôn luônURL trả về có hiệu lực dùng khi thanh toán kết thúc mà chưa thành công.
redirect_automaticallybooleanluôn luônTrang thanh toán có nên tự chuyển hướng sau thành công hay không.
metadataobjectluôn luôn
Metadata nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về. Công cụ thanh toán trong bảng điều khiển thêm nguồn gốc payment_tool (id, kind, title, pricing, requested_amount, request_id); điều này không chứng minh thanh toán. Xác thực callback và hoàn tất invoice.settled một lần mỗi invoice_id.Chi tiết
Metadata nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về. Công cụ thanh toán trong bảng điều khiển thêm nguồn gốc payment_tool (id, kind, title, pricing, requested_amount, request_id); điều này không chứng minh thanh toán. Xác thực callback và hoàn tất invoice.settled một lần mỗi invoice_id.
payment_intents[]object[]luôn luôn
Phương thức thanh toán đã báo giá và trạng thái theo dõi.
payment_railonchain | lightningluôn luônCách truyền thanh toán hóa đơn. Bitcoin trên chuỗi và Lightning có thể cùng asset_id; dùng id ý định cộng trường này, không chỉ ký hiệu. Trường này khác payment_rail máy quét trong danh mục tài sản.Chi tiết
Cách truyền thanh toán hóa đơn. Bitcoin trên chuỗi và Lightning có thể cùng asset_id; dùng id ý định cộng trường này, không chỉ ký hiệu. Trường này khác payment_rail máy quét trong danh mục tài sản.
bolt11string | nullluôn luônYêu cầu thanh toán Lightning, nếu không là null. Thanh toán yêu cầu này bằng ví Lightning, không bao giờ gửi tiền trên chuỗi đến mã băm thanh toán của nó.
asset_decimalsintegerluôn luônĐộ chính xác đơn vị nhỏ nhất. Lightning BTC dùng 11 (millisatoshi), không phải 8 của Bitcoin trên chuỗi. Báo giá theo satoshi nguyên; khoản nhận giữ độ chính xác millisatoshi.
quote_ratedecimal stringluôn luônSố đơn vị tài sản cho một đơn vị tiền tệ hóa đơn, gồm chênh lệch đã khóa. Ví dụ 1.02 USDC mỗi USD. Không phải tỷ giá nghịch đảo.
quote_detailsobject | nullluôn luônNguồn gốc báo giá đã khóa: reference_rate trước chênh lệch, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at và asset_fetched_at. Null trên hóa đơn cũ; không tạo giá trị lịch sử giả.Chi tiết
Nguồn gốc báo giá đã khóa: reference_rate trước chênh lệch, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at và asset_fetched_at. Null trên hóa đơn cũ; không tạo giá trị lịch sử giả.
expected_amountdecimal stringluôn luônSố tài sản chính xác đã khóa phải trả sau chênh lệch và làm tròn lên. Từ 4.1.1, stablecoin tiền pháp định được nhận diện và xác minh (như USDC, USDT, DAI, USDS, EURC) làm tròn lên tối đa hai chữ số thập phân; 1.321 thành 1.33, không bao giờ 1.32. Đây là số tiền dự kiến ngay cả với dung sai không. Tài sản khác giữ độ chính xác thích ứng. Hóa đơn hiện có không bao giờ được định giá lại.Chi tiết
Số tài sản chính xác đã khóa phải trả sau chênh lệch và làm tròn lên. Từ 4.1.1, stablecoin tiền pháp định được nhận diện và xác minh (như USDC, USDT, DAI, USDS, EURC) làm tròn lên tối đa hai chữ số thập phân; 1.321 thành 1.33, không bao giờ 1.32. Đây là số tiền dự kiến ngay cả với dung sai không. Tài sản khác giữ độ chính xác thích ứng. Hóa đơn hiện có không bao giờ được định giá lại.
minimum_payment_amountdecimal stringluôn luônSố tiền nhỏ nhất được chấp nhận là đã trả sau khi áp dụng dung sai hóa đơn.
minimum_payment_amount_atomicinteger stringluôn luônNgưỡng được chấp nhận chính xác theo đơn vị nhỏ nhất của tài sản.
destination_addressstringluôn luônĐịa chỉ nhận trên chuỗi hoặc mã băm thanh toán 64 ký tự với Lightning. Dùng bolt11 để thanh toán Lightning; mã băm không phải địa chỉ Bitcoin.
destination_tagstring | nullluôn luônTham chiếu thanh toán công khai bắt buộc khi hệ thống sử dụng: destination tag XRP, memo ID Stellar hoặc bình luận hóa đơn TON. Null với hệ thống dùng địa chỉ riêng.
Ghi chú sử dụng
- payment_methods chỉ lọc phương thức đang bật của cửa hàng cho hóa đơn này. Bỏ qua/null giữ mọi phương thức cửa hàng; [] không hợp lệ. Tìm gợi ý chain_slug nhỏ và mã tài sản hiển thị trong Dự án → Cửa hàng → Phương thức thanh toán. Danh sách API payment-assets cung cấp chain_slug, asset.symbol và asset.id. Dùng {chain_slug: ethereum, asset_tickers: [USDC, USDT]} cho token Ethereum được chấp nhận; BTC và PEPE hoạt động tương tự trên chuỗi được chọn. Mã không phân biệt hoa thường, giới hạn theo chuỗi và chỉ phân giải trong cửa hàng. Hai hợp đồng được chấp nhận cùng mã trả 400 thay vì chọn một, kể cả khi một hợp đồng chưa sẵn sàng; dùng asset_ids trong trường hợp đó. Tài sản gốc, token danh mục và token tùy chỉnh theo cùng quy tắc. Mỗi chuỗi/hệ thống thanh toán xuất hiện một lần; tối đa 64 phương thức cuối cùng. Merchant 5.4.0+: bỏ qua lựa chọn không xác định, bị tắt, sai chuỗi hoặc không được chấp nhận. Nếu toàn bộ lựa chọn không khớp tài sản đang hoạt động được chấp nhận nào, áp dụng mặc định cửa hàng; nếu có, chỉ dùng lựa chọn khớp. Mục chỉ có chuỗi bao gồm mọi tài sản trên chuỗi đang hoạt động được chấp nhận. Phương thức đang hoạt động được chọn cần ví hợp lệ, adapter máy quét đã cài và tỷ giá đáng tin. Từ 6.0.6, máy quét không khả dụng, thời gian chờ và kiểm tra tình trạng đang chờ/cũ không chặn tạo hóa đơn hay loại phương thức trên chuỗi đã cấu hình. Phát hiện tự thử lại; quyết toán vẫn cần đồng thuận nhà cung cấp và xác nhận. Theo dõi receive_readiness và duy trì nhà cung cấp khả dụng: hóa đơn có thể chưa được xác minh cho đến khi máy quét phục hồi. Cấp địa chỉ phụ Monero và tạo BOLT11 Lightning vẫn cần dịch vụ ví/nút bên ngoài tương ứng. Lỗi trả error.message cùng error.details.payment_methods với chain_slug, asset_ticker, reason_code và, cho chẩn đoán máy quét, required_endpoint_role, healthy_endpoints và required_independent_providers. TRON chấp nhận lịch sử lập chỉ mục hoặc API khối gốc thô solidified được hỗ trợ; riêng tình trạng cơ bản không chứng minh tương thích máy quét. Lỗi định giá xác định tài sản/tiền tệ. Không điều gì bật tài sản chưa được chấp nhận hay đổi chính sách cửa hàng. Trên phiên bản merchant trước 5.4.0, lựa chọn rõ ràng không xác định/không hoạt động gây lỗi. Phương thức hóa đơn hiện có không bao giờ mở rộng khi đổi cài đặt cửa hàng. Lightning phải được chọn riêng. Phát lại giữ phương thức gốc và đổi lựa chọn với cùng Idempotency-Key trả 409.
- checkout_appearance hỗ trợ mọi cài đặt trình bày nêu trên. Trường bỏ qua được kế thừa, mảng thay thế, trường thông báo lồng nhau được gộp; đối tượng thông báo rỗng xóa phạm vi đó. Thiết kế đã phân giải và hình ảnh được lưu cho hóa đơn này mà không sửa cửa hàng. Đọc appearance từ JSON thanh toán công khai để kiểm tra kết quả. Toàn yêu cầu giới hạn 32 KiB và cài đặt đã phân giải giới hạn 20 KiB.
- Đổi checkout_appearance với cùng Idempotency-Key trả 409; thử lại bằng byte thô giống hệt. Giao diện không đổi số tiền, tỷ giá, tài sản được chấp nhận, yêu cầu xác nhận, trạng thái thực hay quyền nhúng. Không HTML, CSS, script hay lấy ảnh từ xa.
- exchange_rate_spread_percent ghi đè mặc định cửa hàng cho hóa đơn này: bỏ qua hoặc gửi null để kế thừa, hoặc gửi "0" để tắt. Báo giá hóa đơn hiện có không bao giờ đổi.
- Chênh lệch áp dụng trước làm tròn lên. Phí vẫn dựa trên số tiền pháp định gốc của hóa đơn, không gồm chênh lệch.
- Luôn gửi expected_amount hoặc expected_amount_atomic được trả về. Làm tròn theo chiều tăng, giới hạn bởi độ chính xác tài sản, 0.1% số tiền và một đơn vị nhỏ của tiền pháp định.
- Thử lại phải giữ cùng thông tin xác thực, Idempotency-Key và byte nội dung chính xác. Đổi chênh lệch với cùng khóa trả 409 idempotency_conflict.
- Phát lại chính xác được kiểm tra trước báo giá mới, DNS callback hay chuẩn bị địa chỉ. Phạm vi thông tin xác thực và quyền dự án/cửa hàng vẫn được kiểm tra mỗi yêu cầu.
- ipn_url có hiệu lực cần bí mật ký IPN của cửa hàng. Từ chối trường nội dung không xác định.
Lỗi
GETLiệt kê hóa đơn/v1/projects/{project_id}/invoicesChỉ đọc
Trả trang tóm tắt hóa đơn gọn theo phạm vi, mới nhất trước, gồm email chỉ dành cho nhà bán hàng và trường khách hàng suy ra từ metadata được nhận diện. Tìm kiếm, trạng thái và bộ lọc cửa hàng được xét phía máy chủ; phản hồi có total và has_more để phân trang nhất quán.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Tham số truy vấn
searchstringTùy chọn tiền tố invoice-id, order-id hoặc email không phân biệt hoa thường; UUID hóa đơn chính xác; hoặc chuỗi con trong mô tả và trường khách hàng được nhận diện. Mọi khóa metadata và giá trị văn bản, số, boolean (kể cả đối tượng/mảng lồng nhau) cũng hỗ trợ tìm tiền tố từ có chỉ mục: mọi từ tìm kiếm phải khớp, dấu câu được coi là dấu phân cách. Bỏ khoảng trắng hai đầu, tối đa 100 ký tự, không ký tự điều khiển. Khớp metadata không thêm metadata thô vào phản hồi danh sách; dùng chi tiết hóa đơn để đọc.Chi tiết
Tùy chọn tiền tố invoice-id, order-id hoặc email không phân biệt hoa thường; UUID hóa đơn chính xác; hoặc chuỗi con trong mô tả và trường khách hàng được nhận diện. Mọi khóa metadata và giá trị văn bản, số, boolean (kể cả đối tượng/mảng lồng nhau) cũng hỗ trợ tìm tiền tố từ có chỉ mục: mọi từ tìm kiếm phải khớp, dấu câu được coi là dấu phân cách. Bỏ khoảng trắng hai đầu, tối đa 100 ký tự, không ký tự điều khiển. Khớp metadata không thêm metadata thô vào phản hồi danh sách; dùng chi tiết hóa đơn để đọc.
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices?search=order-1042&status=processing&limit=50&offset=0" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Accept: application/json'// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices?search=order-1042&status=processing&limit=50&offset=0", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Accept": "application/json"
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices?search=order-1042&status=processing&limit=50&offset=0");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Accept: application/json"],
]);
$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
headers = {
"Accept": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices?search=order-1042&status=processing&limit=50&offset=0",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": [
{
"id": "2f798f9f-01f2-42f0-9d10-5581d6116b4c",
"invoice_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50",
"project_id": "11111111-1111-4111-8111-111111111111",
"store_id": "22222222-2222-4222-8222-222222222222",
"source": "api",
"order_id": "order-1042",
"email": "ada@example.com",
"customer_name": "Ada Lovelace · Example GmbH",
"customer_address": "Example GmbH · 12 Example Street · Suite 2 · 10115 Berlin · Germany (DE) · VAT DE123456789",
"description": "Annual plan",
"amount": "49.9",
"currency": "USD",
"exchange_rate_spread_percent": "0.5",
"underpayment_tolerance_percent": "1",
"status": "processing",
"amount_status": "paid",
"timing_status": "on_time",
"resolution": "automatic",
"sequence": 3,
"winning_payment_intent_id": "33333333-3333-4333-8333-333333333333",
"expires_at": "2026-08-31T18:15:00Z",
"monitoring_expires_at": "2026-09-07T18:15:00Z",
"settled_at": null,
"cancelled_at": null,
"archived_at": null,
"created_at": "2026-08-31T18:00:00Z",
"updated_at": "2026-08-31T18:04:10Z"
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 143,
"has_more": true
}
}Trường phản hồi
data[]object[]
idUUIDluôn luônUUID hóa đơn nội bộ. Không dùng trong đường dẫn chi tiết nhà bán hàng hay trang thanh toán.
invoice_idUUIDluôn luônUUID hóa đơn công khai dùng trong đường dẫn chi tiết nhà bán hàng và trang thanh toán.
emailstring | nullluôn luônEmail khách hàng chỉ dành cho nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về.
customer_namestring | nullluôn luônTên hiển thị suy ra từ metadata riêng firstname, lastname và company.
customer_addressstring | nullluôn luônĐịa chỉ một dòng dành cho nhà bán hàng, suy ra từ metadata riêng company, street, street2, zip, city, country, countryiso2 và vatid.
exchange_rate_spread_percentdecimal stringluôn luônChênh lệch báo giá đã khóa: ghi đè lúc tạo hoặc mặc định cửa hàng khi bỏ qua. Áp dụng trước làm tròn lên; không bao giờ thay đổi trên hóa đơn này.
underpayment_tolerance_percentdecimal stringluôn luônTỷ lệ thiếu tiền được chấp nhận bất biến, chụp lưu khi tạo hóa đơn.
amount_statusamount statusluôn luônnone, partial, paid hoặc overpaid. Hóa đơn số tiền bằng không được cho phép rõ ràng sẽ quyết toán với none và không có phương thức thanh toán.
winning_payment_intent_idUUID | nullluôn luônPhương thức thanh toán dùng để xử lý hóa đơn, khi đã chọn.
monitoring_expires_atRFC 3339 timestampluôn luônMốc kết thúc theo dõi muộn được cấu hình xa nhất trong các phương thức thanh toán.
paginationobject
totalintegerluôn luônTổng dòng khớp bộ lọc dự án, cửa hàng, trạng thái và tìm kiếm trong bản chụp trang.
Ghi chú sử dụng
- Sắp theo created_at giảm dần, rồi id nội bộ giảm dần.
- Mục danh sách là đối tượng InvoiceSummary; email, customer_name và customer_address chỉ dành cho nhà bán hàng. Gọi chi tiết để lấy metadata thô và ý định thanh toán.
- Cho trang tiếp theo, đặt offset thành pagination.offset + pagination.limit chỉ khi has_more true.
- Số lượng và trang được đọc từ cùng một bản chụp cơ sở dữ liệu repeatable-read; ghi đồng thời xuất hiện ở yêu cầu sau.
Lỗi
GETTruy xuất hóa đơn/v1/projects/{project_id}/invoices/{invoice_id}Chỉ đọc
Trả chi tiết hóa đơn nhà bán hàng đầy đủ và URL thanh toán đang hoạt động hiện tại. Dùng tuyến này để thăm dò và đối soát.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Accept: application/json'// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Accept": "application/json"
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Accept: application/json"],
]);
$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
headers = {
"Accept": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {
"id": "2f798f9f-01f2-42f0-9d10-5581d6116b4c",
"invoice_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50",
"project_id": "11111111-1111-4111-8111-111111111111",
"store_id": "22222222-2222-4222-8222-222222222222",
"source": "api",
"order_id": "order-1042",
"email": "ada@example.com",
"customer_name": "Ada Lovelace · Example GmbH",
"customer_address": "Example GmbH · 12 Example Street · Suite 2 · 10115 Berlin · Germany (DE) · VAT DE123456789",
"description": "Annual plan",
"amount": "49.9",
"currency": "USD",
"exchange_rate_spread_percent": "0.5",
"underpayment_tolerance_percent": "1",
"status": "settled",
"amount_status": "paid",
"timing_status": "on_time",
"resolution": "automatic",
"sequence": 4,
"winning_payment_intent_id": "33333333-3333-4333-8333-333333333333",
"expires_at": "2026-08-31T18:15:00Z",
"monitoring_expires_at": "2026-09-07T18:15:00Z",
"settled_at": "2026-08-31T18:05:00Z",
"cancelled_at": null,
"archived_at": null,
"created_at": "2026-08-31T18:00:00Z",
"updated_at": "2026-08-31T18:05:00Z",
"ipn_url": "https://merchant.example/wholly/ipn",
"redirect_url": "https://merchant.example/orders/1042",
"cancel_url": "https://merchant.example/cart",
"redirect_automatically": true,
"checkout_language": "en",
"metadata": { "cart_id": "cart-681", "firstname": "Ada", "lastname": "Lovelace", "street": "12 Example Street", "street2": "Suite 2", "zip": "10115", "city": "Berlin", "country": "Germany", "countryiso2": "DE", "company": "Example GmbH", "vatid": "DE123456789" },
"payment_intents": [
{
"id": "33333333-3333-4333-8333-333333333333",
"asset_id": "10000000-0000-4000-8000-000000000001",
"asset_key": "bip122:000000000019d6689c085ae165831e93/slip44:0",
"chain_slug": "bitcoin",
"network": "mainnet",
"caip_network_id": "bip122:000000000019d6689c085ae165831e93",
"caip_asset_id": "bip122:000000000019d6689c085ae165831e93/slip44:0",
"symbol": "BTC",
"asset_decimals": 8,
"status": "paid",
"finality_mode": "confirmations",
"required_confirmations": 1,
"quote_rate": "0.000009218",
"quote_details": null,
"expected_amount": "0.00046",
"expected_amount_atomic": "46000",
"minimum_payment_amount": "0.0004554",
"minimum_payment_amount_atomic": "45540",
"received_amount": "0.0004554",
"received_amount_atomic": "45540",
"confirmed_amount": "0.0004554",
"confirmed_amount_atomic": "45540",
"destination_address": "bc1q…example",
"destination_tag": null,
"derivation_index": 42,
"quote_expires_at": "2026-08-31T18:15:00Z",
"monitoring_expires_at": "2026-09-07T18:15:00Z",
"next_check_at": null,
"last_checked_at": "2026-08-31T18:05:00Z",
"last_chain_height": 912345,
"last_anchor_hash": "000000000000000000example",
"last_monitor_error": null,
"first_payment_at": "2026-08-31T18:03:00Z",
"fully_paid_at": "2026-08-31T18:03:00Z",
"finalized_at": "2026-08-31T18:05:00Z"
}
]
},
"links": {
"checkout": "https://pay.example.com/invoice/0a6a98db-d93d-48ee-8c3c-fd45f90c4a50"
}
}Trường phản hồi
dataobject
idUUIDluôn luônUUID hóa đơn nội bộ. Không dùng trong đường dẫn chi tiết nhà bán hàng hay trang thanh toán.
invoice_idUUIDluôn luônUUID hóa đơn công khai dùng trong đường dẫn chi tiết nhà bán hàng và trang thanh toán.
emailstring | nullluôn luônEmail khách hàng chỉ dành cho nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về.
customer_namestring | nullluôn luônTên hiển thị suy ra từ metadata riêng firstname, lastname và company.
customer_addressstring | nullluôn luônĐịa chỉ một dòng dành cho nhà bán hàng, suy ra từ metadata riêng company, street, street2, zip, city, country, countryiso2 và vatid.
exchange_rate_spread_percentdecimal stringluôn luônChênh lệch báo giá đã khóa: ghi đè lúc tạo hoặc mặc định cửa hàng khi bỏ qua. Áp dụng trước làm tròn lên; không bao giờ thay đổi trên hóa đơn này.
underpayment_tolerance_percentdecimal stringluôn luônTỷ lệ thiếu tiền được chấp nhận bất biến, chụp lưu khi tạo hóa đơn.
amount_statusamount statusluôn luônnone, partial, paid hoặc overpaid. Hóa đơn số tiền bằng không được cho phép rõ ràng sẽ quyết toán với none và không có phương thức thanh toán.
winning_payment_intent_idUUID | nullluôn luônPhương thức thanh toán dùng để xử lý hóa đơn, khi đã chọn.
monitoring_expires_atRFC 3339 timestampluôn luônMốc kết thúc theo dõi muộn được cấu hình xa nhất trong các phương thức thanh toán.
ipn_urlstring | nullluôn luônĐích IPN có hiệu lực theo hóa đơn. Chỉ phản hồi nhà bán hàng; không có trên trang thanh toán công khai.
cancel_urlstring | nullluôn luônURL trả về có hiệu lực dùng khi thanh toán kết thúc mà chưa thành công.
redirect_automaticallybooleanluôn luônTrang thanh toán có nên tự chuyển hướng sau thành công hay không.
metadataobjectluôn luôn
Metadata nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về. Công cụ thanh toán trong bảng điều khiển thêm nguồn gốc payment_tool (id, kind, title, pricing, requested_amount, request_id); điều này không chứng minh thanh toán. Xác thực callback và hoàn tất invoice.settled một lần mỗi invoice_id.Chi tiết
Metadata nhà bán hàng. Không bao giờ được trang thanh toán công khai trả về. Công cụ thanh toán trong bảng điều khiển thêm nguồn gốc payment_tool (id, kind, title, pricing, requested_amount, request_id); điều này không chứng minh thanh toán. Xác thực callback và hoàn tất invoice.settled một lần mỗi invoice_id.
payment_intents[]object[]luôn luôn
Phương thức thanh toán đã báo giá và trạng thái theo dõi.
payment_railonchain | lightningluôn luônCách truyền thanh toán hóa đơn. Bitcoin trên chuỗi và Lightning có thể cùng asset_id; dùng id ý định cộng trường này, không chỉ ký hiệu. Trường này khác payment_rail máy quét trong danh mục tài sản.Chi tiết
Cách truyền thanh toán hóa đơn. Bitcoin trên chuỗi và Lightning có thể cùng asset_id; dùng id ý định cộng trường này, không chỉ ký hiệu. Trường này khác payment_rail máy quét trong danh mục tài sản.
bolt11string | nullluôn luônYêu cầu thanh toán Lightning, nếu không là null. Thanh toán yêu cầu này bằng ví Lightning, không bao giờ gửi tiền trên chuỗi đến mã băm thanh toán của nó.
asset_decimalsintegerluôn luônĐộ chính xác đơn vị nhỏ nhất. Lightning BTC dùng 11 (millisatoshi), không phải 8 của Bitcoin trên chuỗi. Báo giá theo satoshi nguyên; khoản nhận giữ độ chính xác millisatoshi.
quote_ratedecimal stringluôn luônSố đơn vị tài sản cho một đơn vị tiền tệ hóa đơn, gồm chênh lệch đã khóa. Ví dụ 1.02 USDC mỗi USD. Không phải tỷ giá nghịch đảo.
quote_detailsobject | nullluôn luônNguồn gốc báo giá đã khóa: reference_rate trước chênh lệch, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at và asset_fetched_at. Null trên hóa đơn cũ; không tạo giá trị lịch sử giả.Chi tiết
Nguồn gốc báo giá đã khóa: reference_rate trước chênh lệch, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at và asset_fetched_at. Null trên hóa đơn cũ; không tạo giá trị lịch sử giả.
expected_amountdecimal stringluôn luônSố tài sản chính xác đã khóa phải trả sau chênh lệch và làm tròn lên. Từ 4.1.1, stablecoin tiền pháp định được nhận diện và xác minh (như USDC, USDT, DAI, USDS, EURC) làm tròn lên tối đa hai chữ số thập phân; 1.321 thành 1.33, không bao giờ 1.32. Đây là số tiền dự kiến ngay cả với dung sai không. Tài sản khác giữ độ chính xác thích ứng. Hóa đơn hiện có không bao giờ được định giá lại.Chi tiết
Số tài sản chính xác đã khóa phải trả sau chênh lệch và làm tròn lên. Từ 4.1.1, stablecoin tiền pháp định được nhận diện và xác minh (như USDC, USDT, DAI, USDS, EURC) làm tròn lên tối đa hai chữ số thập phân; 1.321 thành 1.33, không bao giờ 1.32. Đây là số tiền dự kiến ngay cả với dung sai không. Tài sản khác giữ độ chính xác thích ứng. Hóa đơn hiện có không bao giờ được định giá lại.
minimum_payment_amountdecimal stringluôn luônSố tiền nhỏ nhất được chấp nhận là đã trả sau khi áp dụng dung sai hóa đơn.
minimum_payment_amount_atomicinteger stringluôn luônNgưỡng được chấp nhận chính xác theo đơn vị nhỏ nhất của tài sản.
destination_addressstringluôn luônĐịa chỉ nhận trên chuỗi hoặc mã băm thanh toán 64 ký tự với Lightning. Dùng bolt11 để thanh toán Lightning; mã băm không phải địa chỉ Bitcoin.
destination_tagstring | nullluôn luônTham chiếu thanh toán công khai bắt buộc khi hệ thống sử dụng: destination tag XRP, memo ID Stellar hoặc bình luận hóa đơn TON. Null với hệ thống dùng địa chỉ riêng.
Ghi chú sử dụng
- Tra cứu theo phạm vi chủ động trả invoice_not_found khi ID công khai không thuộc dự án được cấp quyền.
- links.checkout dùng Cửa hàng → Cơ bản → Tên miền cửa hàng: tên máy chủ thanh toán đang hoạt động của cửa hàng này, rồi lựa chọn của cửa hàng mặc định, rồi máy chủ chính hệ thống. Bỏ qua máy chủ đã ngừng/nháp hoặc sai dịch vụ. Điều này cũng áp dụng cho phản hồi tạo và MCP; liên kết được phân giải lúc phản hồi, kể cả phát lại idempotent. Liên kết callback đã ký đóng băng lúc tạo sự kiện, không viết lại khi thử lại. Những tùy chọn này chỉ tạo liên kết; không chuyển hướng lưu lượng hay đổi giới hạn IP.
Lỗi
GETLiệt kê khoản thanh toán của hóa đơn/v1/projects/{project_id}/invoices/{invoice_id}/paymentsChỉ đọc
Toàn bộ lịch sử chuyển tiền hiện tại, gồm quan sát bị vô hiệu hóa. Dùng khi callback đánh dấu payments_truncated. Đây là trạng thái hiện tại, không phải dựng lại sự kiện cũ.
Xác thực & header
| Header | Yêu cầu có mặt | Quy tắc |
|---|---|---|
| Authorization | bắt buộc | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | khuyến nghị | application/json |
Tham số đường dẫn
Tham số truy vấn
Yêu cầu
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID/payments?limit=25&offset=0" \
--header "Authorization: Bearer $WHOLLY_TOKEN" \
--header 'Accept: application/json'// 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");
const response = await fetch("https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID/payments?limit=25&offset=0", {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Accept": "application/json"
},
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'); }
$ch = curl_init("https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID/payments?limit=25&offset=0");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Accept: application/json"],
]);
$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
headers = {
"Accept": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
request = Request("https://api.example.com/v1/projects/YOUR_PROJECT_ID/invoices/YOUR_PUBLIC_INVOICE_ID/payments?limit=25&offset=0",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"invoice_id": "11111111-2222-4333-8444-555555555555",
"data": [{
"payment_id": "44444444-4444-4444-8444-444444444444",
"payment_method_id": "33333333-3333-4333-8333-333333333333",
"transaction_id": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"payment_hash": null,
"event_index": 12,
"payment_rail": "onchain",
"chain_slug": "ethereum",
"network": "mainnet",
"asset_id": "55555555-5555-4555-8555-555555555555",
"asset_key": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"caip_asset_id": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"symbol": "USDC",
"asset_decimals": 6,
"amount": "58.17342",
"amount_atomic": "58173420",
"status": "final",
"counts_towards_received": true,
"confirmations": 2,
"block_height": 25975377,
"observed_at": "2026-09-14T12:03:00Z",
"chain_time": "2026-09-14T12:02:48Z",
"finalized_at": "2026-09-14T12:04:00Z",
"explorer_name": "Etherscan",
"explorer_url": "https://etherscan.io/tx/0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}],
"pagination": {"limit": 25, "offset": 0, "total": 1, "has_more": false}
}Trường phản hồi
invoice_idstringdata[]object[]
payment_idstringpayment_method_idstringtransaction_idstringpayment_hashJSON | nullevent_indexintegerpayment_railstringchain_slugstringnetworkstringasset_idstringasset_keystringcaip_asset_idstringsymbolstringasset_decimalsintegeramountstringamount_atomicstringstatusstringcounts_towards_receivedbooleanconfirmationsintegerblock_heightintegerobserved_atstringchain_timestringfinalized_atstringexplorer_namestringexplorer_urlstringGhi chú sử dụng
- Quan sát là log token, đầu ra UTXO hoặc khoản chuyển của hệ thống khác, không nhất thiết là mã băm giao dịch duy nhất. Loại trùng bằng payment_id; transaction_id cộng event_index xác định khoản chuyển trên chuỗi.
- status là detected, confirming, final, reorged, replaced hoặc invalid. Chỉ quan sát counts_towards_received đóng góp vào số tiền đã nhận. Không bao giờ cộng số tiền giữa các tài sản khác nhau.
- Bản ghi Lightning dùng payment_hash với transaction_id, confirmations và liên kết trình khám phá null; độ chính xác BTC là 11 (millisatoshi). Không cung cấp preimage, BOLT11 hay bí mật ví.
- Sắp theo observed_at giảm dần, rồi payment_id giảm dần. Số lượng và trang dùng một bản chụp repeatable-read; trang sau có thể đổi khi thanh toán đến. Loại trùng bằng payment_id khi phân trang hóa đơn đang hoạt động.
- Áp dụng phạm vi dự án chỉ đọc, giới hạn IP và giới hạn tần suất theo thông tin xác thực hiện có. Không bao giờ theo liên kết do callback cung cấp với token của bạn trừ khi origin khớp máy chủ API đã cấu hình.
Lỗi
GETKhung trang thanh toán/Công khai
Đường dẫn gốc máy chủ thanh toán được quản lý phục vụ ứng dụng thanh toán mà chưa chọn hóa đơn. Tích hợp khách hàng thường nên dùng links.checkout.
Xác thực & header
Công khai
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/" \
--output 'checkout.html'// Node.js 18+ · run on your server, never in browser code.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://pay.example.com/", {
method: "GET",
headers: {},
redirect: "error",
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
await writeFile("checkout.html", Buffer.from(await response.arrayBuffer()));<?php
// PHP 8+ with the cURL extension; run on your server.
$ch = curl_init("https://pay.example.com/");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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"); }
file_put_contents("checkout.html", $response);# Python 3 · standard library; run on your server.
import json
from pathlib import Path
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://pay.example.com/",
method="GET", headers=headers)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
Path("checkout.html").write_bytes(response.read())Phản hồi 200 text/html
Phản hồi ví dụ
<!doctype html>
<!-- Hosted Wholly Crypto checkout shell -->Ghi chú sử dụng
- Không cần token bearer.
- Lớp biên thanh toán được quản lý cho phép GET/HEAD và từ chối phương thức khác.
Lỗi
GETTrang thanh toán được lưu trữ/invoice/{invoice_id}Công khai
Trang thanh toán HTML cho khách hàng. Trang lấy JSON an toàn cho thanh toán từ cùng máy chủ thanh toán. Từ chối nhúng trừ khi cửa hàng bật và cho phép rõ origin HTTPS của trang cha.
Xác thực & header
Công khai
Tham số đường dẫn
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/invoice/YOUR_PUBLIC_INVOICE_ID" \
--output 'checkout.html'// Node.js 18+ · run on your server, never in browser code.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://pay.example.com/invoice/YOUR_PUBLIC_INVOICE_ID", {
method: "GET",
headers: {},
redirect: "error",
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
await writeFile("checkout.html", Buffer.from(await response.arrayBuffer()));<?php
// PHP 8+ with the cURL extension; run on your server.
$ch = curl_init("https://pay.example.com/invoice/YOUR_PUBLIC_INVOICE_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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"); }
file_put_contents("checkout.html", $response);# Python 3 · standard library; run on your server.
import json
from pathlib import Path
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://pay.example.com/invoice/YOUR_PUBLIC_INVOICE_ID",
method="GET", headers=headers)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
Path("checkout.html").write_bytes(response.read())Phản hồi 200 text/html
Phản hồi ví dụ
<!doctype html>
<!-- Hosted Wholly Crypto checkout application -->Ghi chú sử dụng
- Không chấp nhận hay cần token bearer.
- Bản thân khung HTML trả 200 ngay cả khi không có hóa đơn; yêu cầu JSON thanh toán sau đó nhận invoice_not_found.
- Phản hồi là no-store, noindex và có CSP frame-ancestors riêng theo hóa đơn.
- Dự án/cửa hàng bị tắt hoặc hóa đơn không xác định không cung cấp dữ liệu thanh toán.
Lỗi
GETHóa đơn an toàn cho trang thanh toán/checkout-api/invoices/{invoice_id}Công khai
Chỉ trả trường cần để dựng trang thanh toán. Chủ động bỏ ID nội bộ, email khách hàng và trường địa chỉ suy ra, URL IPN, metadata nhà bán hàng, ID ví, đường dẫn dẫn xuất và chẩn đoán theo dõi.
Xác thực & header
Công khai
Tham số đường dẫn
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID" \
--header 'Accept: application/json'// Node.js 18+ · run on your server, never in browser code.
const response = await fetch("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID", {
method: "GET",
headers: {
"Accept": "application/json"
},
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.
$ch = curl_init("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["Accept: application/json"],
]);
$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
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {
"Accept": "application/json"
}
request = Request("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {
"invoice_id": "0a6a98db-d93d-48ee-8c3c-fd45f90c4a50",
"order_id": "order-1042",
"description": "Annual plan",
"amount": "49.9",
"currency": "USD",
"exchange_rate_spread_percent": "0.5",
"underpayment_tolerance_percent": "1",
"status": "processing",
"amount_status": "partial",
"timing_status": "on_time",
"sequence": 3,
"active_payment_method_id": "33333333-3333-4333-8333-333333333333",
"payment_method_locked": true,
"server_time": "2026-08-31T18:10:00Z",
"expires_at": "2026-08-31T18:15:00Z",
"expires_in_seconds": 300,
"payment_open": true,
"redirect_url": "https://merchant.example/orders/1042",
"cancel_url": "https://merchant.example/cart",
"redirect_automatically": true,
"checkout_language": "en",
"project": {
"name": "Example project",
"checkout_title": "Complete your payment",
"checkout_description": "Send the exact amount shown.",
"theme": "system",
"accent_color": "#42e39b",
"logo_url": "/checkout-api/invoices/…/logo/…/image.png"
},
"store": { "name": "Online shop" },
"payment_methods": [
{
"id": "33333333-3333-4333-8333-333333333333",
"asset_key": "bip122:000000000019d6689c085ae165831e93/slip44:0",
"chain_slug": "bitcoin",
"chain_name": "Bitcoin",
"network": "mainnet",
"caip_network_id": "bip122:000000000019d6689c085ae165831e93",
"caip_asset_id": "bip122:000000000019d6689c085ae165831e93/slip44:0",
"asset_name": "Bitcoin",
"symbol": "BTC",
"asset_icon_url": "/assets/coingecko/bitcoin.png",
"asset_kind": "native",
"contract_address": null,
"token_standard": null,
"asset_decimals": 8,
"status": "partial",
"payable": true,
"finality_mode": "confirmations",
"required_confirmations": 1,
"expected_amount": "0.00046",
"expected_amount_atomic": "46000",
"minimum_payment_amount": "0.0004554",
"minimum_payment_amount_atomic": "45540",
"received_amount": "0.0002",
"received_amount_atomic": "20000",
"remaining_amount": "0.0002554",
"remaining_amount_atomic": "25540",
"confirmed_amount": "0",
"confirmed_amount_atomic": "0",
"destination_address": "bc1q…example",
"destination_tag": null,
"quote_expires_at": "2026-08-31T18:15:00Z",
"payment_uri": "bitcoin:bc1q…example?amount=0.00026",
"qr_url": "/checkout-api/invoices/…/payment-methods/…/qr.svg?sequence=3&amount_atomic=26000",
"address_explorer_name": "mempool.space",
"address_explorer_url": "https://mempool.space/address/…",
"transaction_count": 0,
"transactions_truncated": false,
"transactions": []
}
]
}
}Trường phản hồi
dataobject
exchange_rate_spread_percentdecimal stringluôn luônChênh lệch báo giá có hiệu lực khóa lúc tạo, gồm ghi đè theo hóa đơn.
underpayment_tolerance_percentdecimal stringluôn luônTỷ lệ thiếu tiền được chấp nhận cho hóa đơn này.
amount_statusamount statusluôn luônnone, partial, paid hoặc overpaid. Hóa đơn số tiền bằng không được cho phép rõ ràng sẽ quyết toán với none và không có phương thức thanh toán.
active_payment_method_idUUID | nullluôn luônPhương thức thanh toán trong danh sách đã nhận tiền. Trang thanh toán giữ phương thức này để không tiếp tục thanh toán thiếu bằng tài sản không tương thích.
server_timeRFC 3339 timestampluôn luônĐồng hồ máy chủ ghi cho phản hồi này; dùng cùng expires_at để tránh lệch đồng hồ thiết bị khách hàng.
expires_in_secondsintegerluôn luônSố giây nguyên còn lại tại server_time, làm tròn lên và chặn thấp nhất ở không.
payment_openbooleanluôn luônChỉ true khi hóa đơn new hoặc processing còn trước hạn và có ít nhất một phương thức có thể thanh toán còn tiền phải trả.
cancel_urlstring | nullluôn luônĐích trả về cho khách hàng khi rời đi mà chưa quyết toán thành công.
projectobjectluôn luôn
name, checkout_title, checkout_description, theme, accent_color và logo_url.
appearanceobjectluôn luôn
Trình bày có hiệu lực: ghi đè theo hóa đơn đã đóng băng nếu được cung cấp, nếu không là thiết kế cửa hàng hiện tại. Không bao giờ đổi trường tài chính hay cảnh báo an toàn.
inherit_default_storebooleanluôn luônTrue khi cửa hàng mặc định của dự án cung cấp giao diện này. False cho cửa hàng độc lập và ghi đè hóa đơn đóng băng.
invoice_overridebooleanluôn luônTrue khi checkout_appearance được cung cấp lúc tạo hóa đơn. Bỏ qua/null giữ false.
titlestringluôn luônTiêu đề nhà bán hàng, thông điệp trên và dưới dạng văn bản thuần. intro thay customer_message; nội dung cũ đã lưu được giữ. Không bao giờ xử lý như mã đánh dấu.
introstringluôn luônTiêu đề nhà bán hàng, thông điệp trên và dưới dạng văn bản thuần. intro thay customer_message; nội dung cũ đã lưu được giữ. Không bao giờ xử lý như mã đánh dấu.
outrostringluôn luônTiêu đề nhà bán hàng, thông điệp trên và dưới dạng văn bản thuần. intro thay customer_message; nội dung cũ đã lưu được giữ. Không bao giờ xử lý như mã đánh dấu.
customer_messagestringluôn luônBí danh tương thích của intro đã ngừng khuyến nghị. Dùng intro cho tích hợp mới.
accent_colorstringluôn luônMàu #RRGGBB nghiêm ngặt. Màu tùy chọn rỗng cho giá trị tự động; tương phản tiền cảnh được tính toán.
background_colorstringluôn luônMàu #RRGGBB nghiêm ngặt. Màu tùy chọn rỗng cho giá trị tự động; tương phản tiền cảnh được tính toán.
card_colorstringluôn luônMàu #RRGGBB nghiêm ngặt. Màu tùy chọn rỗng cho giá trị tự động; tương phản tiền cảnh được tính toán.
button_colorstringluôn luônMàu #RRGGBB nghiêm ngặt. Màu tùy chọn rỗng cho giá trị tự động; tương phản tiền cảnh được tính toán.
logo_alignmentstringluôn luônsmall, medium hoặc large; left hoặc center. Ảnh vừa khung, không bị cắt.
imagesobjectluôn luônURL logo_light, logo_dark và favicon tùy chọn: ảnh PNG đã chuẩn hóa, cùng origin, có giới hạn phạm vi.
show_order_idbooleanluôn luônHiển thị ID đơn hàng, mô tả dưới tiêu đề và mở sẵn ID đơn hàng. Số tiền vẫn hiển thị; đây là điều khiển hiển thị, không che dữ liệu.
show_descriptionbooleanluôn luônHiển thị ID đơn hàng, mô tả dưới tiêu đề và mở sẵn ID đơn hàng. Số tiền vẫn hiển thị; đây là điều khiển hiển thị, không che dữ liệu.
details_expandedbooleanluôn luônHiển thị ID đơn hàng, mô tả dưới tiêu đề và mở sẵn ID đơn hàng. Số tiền vẫn hiển thị; đây là điều khiển hiển thị, không che dữ liệu.
show_project_namebooleanluôn luônMerchant 5.6.0+: hiển thị tên phần đầu. Cả hai mặc định true. Danh tính dự án/cửa hàng vẫn có trong JSON.
show_store_namebooleanluôn luônMerchant 5.6.0+: hiển thị tên phần đầu. Cả hai mặc định true. Danh tính dự án/cửa hàng vẫn có trong JSON.
featured_chains[]arrayluôn luônTùy chọn có thứ tự, chỉ áp dụng cho phương thức đã có trong hóa đơn. Bỏ qua phương thức thiếu hoặc bị tắt.
featured_asset_ids[]arrayluôn luônTùy chọn có thứ tự, chỉ áp dụng cho phương thức đã có trong hóa đơn. Bỏ qua phương thức thiếu hoặc bị tắt.
default_asset_idUUID | nullluôn luônPhương thức ban đầu được gợi ý. Tùy chọn khách hàng được ghi nhớ hợp lệ hoặc phương thức đã nhận tiền được ưu tiên.
messagesobjectluôn luôn
Văn bản thuần cho en, de, es, pt-BR, it, ru, zh-CN, fr, ko và ja, theo khóa waiting, confirming, paid, underpaid và expired. Dùng tiếng Anh dự phòng khi thiếu thông báo nhà bán hàng. Chỉ bổ sung; không bao giờ thay trạng thái thực. Nội dung do nhà bán hàng viết không được tự dịch.Chi tiết
Văn bản thuần cho en, de, es, pt-BR, it, ru, zh-CN, fr, ko và ja, theo khóa waiting, confirming, paid, underpaid và expired. Dùng tiếng Anh dự phòng khi thiếu thông báo nhà bán hàng. Chỉ bổ sung; không bao giờ thay trạng thái thực. Nội dung do nhà bán hàng viết không được tự dịch.
support_emailstringluôn luônThông tin liên hệ và liên kết HTTPS tùy chọn, không có thông tin xác thực trong URL. Liên kết ngoài mở trong cửa sổ mới.
support_urlstringluôn luônThông tin liên hệ và liên kết HTTPS tùy chọn, không có thông tin xác thực trong URL. Liên kết ngoài mở trong cửa sổ mới.
terms_urlstringluôn luônThông tin liên hệ và liên kết HTTPS tùy chọn, không có thông tin xác thực trong URL. Liên kết ngoài mở trong cửa sổ mới.
privacy_urlstringluôn luônThông tin liên hệ và liên kết HTTPS tùy chọn, không có thông tin xác thực trong URL. Liên kết ngoài mở trong cửa sổ mới.
return_button_textstringluôn luônChỉ nhãn tùy chọn. Đích thành công/hủy và chính sách chuyển hướng vẫn thuộc hóa đơn.
show_return_buttonbooleanluôn luônHiển thị nút quay lại/hủy thủ công; mặc định true. Áp dụng cho trạng thái hoạt động và kết thúc, không áp dụng cho chuyển hướng thành công tự động. Có từ merchant 8.1.4.
payment_methods[]object[]luôn luôn
Phương thức thanh toán an toàn cho trang thanh toán.
payment_railonchain | lightningluôn luônLightning vẫn là phương thức Bitcoin, tách biệt với BTC trên chuỗi. Nhận diện lựa chọn bằng id ý định và hệ thống thanh toán, không chỉ asset_id.
bolt11string | nullluôn luônYêu cầu Lightning đã ký; null với phương thức trên chuỗi. Không bao giờ thanh toán sau khi payable thành false.
payment_hashstring | nullluôn luônMã băm thanh toán Lightning để đối soát, không phải địa chỉ nhận. Null với phương thức trên chuỗi.
asset_idUUIDluôn luônUUID tài sản dùng bởi tùy chọn giao diện; khác id ý định thanh toán của hóa đơn này.
caip_asset_idstring | nullluôn luônDanh tính tài sản chính tắc chính xác, gồm hợp đồng hoặc mint token đã xác minh khi áp dụng.
asset_icon_urlstring | nullluôn luônBiểu tượng tài sản lưu đệm cục bộ cùng origin, hoặc null khi không có ánh xạ CoinGecko đã xác minh.
contract_addressstring | nullluôn luônHợp đồng ERC-20 hoặc mint SPL chính tắc cho token; null với tiền gốc.
token_standarderc20 | spl-token | nullluôn luônThành phần xử lý token đã xác minh, hoặc null với tiền gốc.
asset_decimalsintegerluôn luônĐộ chính xác đơn vị nhỏ nhất: 11 cho millisatoshi Lightning BTC, 8 cho satoshi BTC trên chuỗi.
payablebooleanluôn luônChỉ true khi đúng phương thức này hiện có thể nhận thanh toán; false cho phương thức không hoạt động sau khi tài sản khác nhận tiền.
expected_amountdecimalluôn luônBáo giá đã khóa đầy đủ theo đơn vị hiển thị và đơn vị thực trên chuỗi. Stablecoin tiền pháp định được nhận diện dùng tối đa hai chữ số thập phân cho báo giá, luôn làm tròn lên sau chênh lệch; tài sản khác dùng độ chính xác thích ứng. Số chữ số thập phân thực của token, tiền đã nhận và phần còn lại của thanh toán một phần giữ chính xác. Dùng nguyên số tiền được trả về.Chi tiết
Báo giá đã khóa đầy đủ theo đơn vị hiển thị và đơn vị thực trên chuỗi. Stablecoin tiền pháp định được nhận diện dùng tối đa hai chữ số thập phân cho báo giá, luôn làm tròn lên sau chênh lệch; tài sản khác dùng độ chính xác thích ứng. Số chữ số thập phân thực của token, tiền đã nhận và phần còn lại của thanh toán một phần giữ chính xác. Dùng nguyên số tiền được trả về.
expected_amount_atomicinteger stringluôn luônBáo giá đã khóa đầy đủ theo đơn vị hiển thị và đơn vị thực trên chuỗi. Stablecoin tiền pháp định được nhận diện dùng tối đa hai chữ số thập phân cho báo giá, luôn làm tròn lên sau chênh lệch; tài sản khác dùng độ chính xác thích ứng. Số chữ số thập phân thực của token, tiền đã nhận và phần còn lại của thanh toán một phần giữ chính xác. Dùng nguyên số tiền được trả về.Chi tiết
Báo giá đã khóa đầy đủ theo đơn vị hiển thị và đơn vị thực trên chuỗi. Stablecoin tiền pháp định được nhận diện dùng tối đa hai chữ số thập phân cho báo giá, luôn làm tròn lên sau chênh lệch; tài sản khác dùng độ chính xác thích ứng. Số chữ số thập phân thực của token, tiền đã nhận và phần còn lại của thanh toán một phần giữ chính xác. Dùng nguyên số tiền được trả về.
minimum_payment_amountdecimalluôn luônNgưỡng quyết toán được chấp nhận sau khi áp dụng dung sai thiếu tiền.
minimum_payment_amount_atomicinteger stringluôn luônNgưỡng quyết toán được chấp nhận sau khi áp dụng dung sai thiếu tiền.
remaining_amountdecimal stringluôn luônSố tiền hiển thị chính xác còn cần để đạt ngưỡng được chấp nhận, chặn thấp nhất ở không.
remaining_amount_atomicinteger stringluôn luônPhần thiếu tới ngưỡng được chấp nhận theo đơn vị nhỏ nhất. Đây không phải số tiền được yêu cầu thanh toán: dung sai chỉ ảnh hưởng việc chấp nhận.
destination_addressstringluôn luônĐích trên chuỗi và tham chiếu tùy chọn. Với Lightning đây là mã băm thanh toán không có tag; hãy thanh toán bolt11/payment_uri.
destination_tagstring|nullluôn luônĐích trên chuỗi và tham chiếu tùy chọn. Với Lightning đây là mã băm thanh toán không có tag; hãy thanh toán bolt11/payment_uri.
payment_uristring | nullluôn luônYêu cầu theo chuỗi: ERC-681, Solana Pay, URI gốc hoặc lightning:<bolt11>. Yêu cầu có số tiền dùng toàn bộ số tiền dự kiến trừ tiền đã nhận, không bao giờ dùng ngưỡng dung sai. Null khi payable false, kể cả sau khi chấp nhận phần thiếu trong dung sai. QR Lightning mã hóa yêu cầu Lightning đầy đủ, không phải mã băm thanh toán.Chi tiết
Yêu cầu theo chuỗi: ERC-681, Solana Pay, URI gốc hoặc lightning:<bolt11>. Yêu cầu có số tiền dùng toàn bộ số tiền dự kiến trừ tiền đã nhận, không bao giờ dùng ngưỡng dung sai. Null khi payable false, kể cả sau khi chấp nhận phần thiếu trong dung sai. QR Lightning mã hóa yêu cầu Lightning đầy đủ, không phải mã băm thanh toán.
qr_urlpath | nullluôn luônĐường dẫn QR SVG cùng origin, có phiên bản theo trình tự và phần tiền còn lại chính xác, hoặc null khi payable false. SVG là no-store.
address_explorer_namestring|nullluôn luônTrình khám phá mainnet dự phòng đã xác thực nơi được hỗ trợ.
address_explorer_urlstring|nullluôn luônTrình khám phá mainnet dự phòng đã xác thực nơi được hỗ trợ.
transaction_countintegerluôn luônTổng số giao dịch công khai hợp lệ khác nhau đã quan sát cho phương thức này.
transactions_truncatedbooleanluôn luônTrue khi transaction_count vượt số giao dịch gần đây trong danh sách được trả.
transactions[]object[]luôn luôn
Tối đa 10 giao dịch công khai hợp lệ mới nhất. Tổng tiền nhận chính xác độc lập với giới hạn hiển thị này.
Ghi chú sử dụng
- Không cần token bearer.
- Cache-Control là no-store và tắt lập chỉ mục tìm kiếm.
- Coi invoice_id là dữ liệu cấp khả năng truy cập cho khách hàng; tránh công bố không cần thiết.
- asset_icon_url là tài nguyên cục bộ cùng origin; trang thanh toán khách hàng không bao giờ cần liên hệ CoinGecko để hiển thị.
- Khi destination_tag khác null, hiển thị và sao chép bên cạnh địa chỉ: đây là destination tag XRP, memo ID Stellar hoặc bình luận hóa đơn TON bắt buộc và phải gửi chính xác.
- Với token đã xác minh, asset_kind là token, contract_address xác định đúng hợp đồng ERC-20 hoặc mint SPL, token_standard xác định hệ thống xử lý và payment_uri mang danh tính token đó.
Lỗi
GETXem trước trang thanh toán của cửa hàng/invoice/preview/{project_id}Công khai
Hiển thị giao diện cửa hàng đã lưu với số tiền minh họa và metadata thực của tài sản được chấp nhận. Chuyển giữa ví dụ waiting, confirming, paid, underpaid và expired mà không tạo thanh toán.
Xác thực & header
Công khai
Tham số đường dẫn
Tham số truy vấn
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/invoice/preview/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID&state=confirming" \
--output 'checkout-preview.html'// Node.js 18+ · run on your server, never in browser code.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://pay.example.com/invoice/preview/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID&state=confirming", {
method: "GET",
headers: {},
redirect: "error",
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
await writeFile("checkout-preview.html", Buffer.from(await response.arrayBuffer()));<?php
// PHP 8+ with the cURL extension; run on your server.
$ch = curl_init("https://pay.example.com/invoice/preview/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID&state=confirming");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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"); }
file_put_contents("checkout-preview.html", $response);# Python 3 · standard library; run on your server.
import json
from pathlib import Path
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://pay.example.com/invoice/preview/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID&state=confirming",
method="GET", headers=headers)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
Path("checkout-preview.html").write_bytes(response.read())Phản hồi 200 text/html
Phản hồi ví dụ
<!doctype html>
<!-- Hosted branding preview; no invoice is created -->Ghi chú sử dụng
- Bản xem trước chỉ phục vụ thương hiệu và không bao giờ được gửi cho khách hàng làm yêu cầu thanh toán.
- Không có địa chỉ nhận, QR trả tiền được, thao tác ví, chuyển hướng hay thăm dò thanh toán. Ví dụ không đổi trạng thái hóa đơn thực.
- Phản hồi là no-store, noindex và không thể nhúng.
Lỗi
GETDữ liệu xem trước trang thanh toán/checkout-api/previews/{project_id}Công khai
Trả giao diện cửa hàng có hiệu lực và metadata an toàn của tài sản được chấp nhận. payment_methods vẫn rỗng; preview_methods không chứa địa chỉ thanh toán, báo giá hay dữ liệu ví riêng.
Xác thực & header
Công khai
Tham số đường dẫn
Tham số truy vấn
store_idUUID,tùy chọnPhải thuộc dự án này; ID không khớp trả 404. Từ chối trường truy vấn không xác định.
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID" \
--header 'Accept: application/json'// Node.js 18+ · run on your server, never in browser code.
const response = await fetch("https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID", {
method: "GET",
headers: {
"Accept": "application/json"
},
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.
$ch = curl_init("https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ["Accept: application/json"],
]);
$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
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {
"Accept": "application/json"
}
request = Request("https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID?store_id=YOUR_STORE_ID",
method="GET", headers=headers)
# 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))Phản hồi 200 application/json
Phản hồi ví dụ
{
"data": {
"preview": true,
"invoice_id": "YOUR_PROJECT_ID",
"amount": "100.00",
"currency": "USD",
"project": {
"name": "Example project",
"checkout_title": "Complete your payment",
"checkout_description": "Choose a network and send the exact amount shown.",
"theme": "system",
"accent_color": "#42e39b",
"logo_url": "/checkout-api/previews/…/logo/…/image.png"
},
"appearance": {"inherit_default_store": true, "theme": "system", "accent_color": "#42E39B", "images": {}},
"preview_methods": [],
"payment_methods": []
}
}Trường phản hồi
dataobject
previewbooleaninvoice_idstringamountstringcurrencystringprojectobject
appearanceobject
inherit_default_storebooleanluôn luônTrue khi cửa hàng mặc định của dự án cung cấp giao diện này. False cho cửa hàng độc lập và ghi đè hóa đơn đóng băng.
invoice_overridebooleanluôn luônTrue khi checkout_appearance được cung cấp lúc tạo hóa đơn. Bỏ qua/null giữ false.
titlestringluôn luônTiêu đề nhà bán hàng, thông điệp trên và dưới dạng văn bản thuần. intro thay customer_message; nội dung cũ đã lưu được giữ. Không bao giờ xử lý như mã đánh dấu.
introstringluôn luônTiêu đề nhà bán hàng, thông điệp trên và dưới dạng văn bản thuần. intro thay customer_message; nội dung cũ đã lưu được giữ. Không bao giờ xử lý như mã đánh dấu.
outrostringluôn luônTiêu đề nhà bán hàng, thông điệp trên và dưới dạng văn bản thuần. intro thay customer_message; nội dung cũ đã lưu được giữ. Không bao giờ xử lý như mã đánh dấu.
customer_messagestringluôn luônBí danh tương thích của intro đã ngừng khuyến nghị. Dùng intro cho tích hợp mới.
accent_colorstringluôn luônMàu #RRGGBB nghiêm ngặt. Màu tùy chọn rỗng cho giá trị tự động; tương phản tiền cảnh được tính toán.
background_colorstringluôn luônMàu #RRGGBB nghiêm ngặt. Màu tùy chọn rỗng cho giá trị tự động; tương phản tiền cảnh được tính toán.
card_colorstringluôn luônMàu #RRGGBB nghiêm ngặt. Màu tùy chọn rỗng cho giá trị tự động; tương phản tiền cảnh được tính toán.
button_colorstringluôn luônMàu #RRGGBB nghiêm ngặt. Màu tùy chọn rỗng cho giá trị tự động; tương phản tiền cảnh được tính toán.
logo_alignmentstringluôn luônsmall, medium hoặc large; left hoặc center. Ảnh vừa khung, không bị cắt.
imagesobjectluôn luônURL logo_light, logo_dark và favicon tùy chọn: ảnh PNG đã chuẩn hóa, cùng origin, có giới hạn phạm vi.
show_order_idbooleanluôn luônHiển thị ID đơn hàng, mô tả dưới tiêu đề và mở sẵn ID đơn hàng. Số tiền vẫn hiển thị; đây là điều khiển hiển thị, không che dữ liệu.
show_descriptionbooleanluôn luônHiển thị ID đơn hàng, mô tả dưới tiêu đề và mở sẵn ID đơn hàng. Số tiền vẫn hiển thị; đây là điều khiển hiển thị, không che dữ liệu.
details_expandedbooleanluôn luônHiển thị ID đơn hàng, mô tả dưới tiêu đề và mở sẵn ID đơn hàng. Số tiền vẫn hiển thị; đây là điều khiển hiển thị, không che dữ liệu.
show_project_namebooleanluôn luônMerchant 5.6.0+: hiển thị tên phần đầu. Cả hai mặc định true. Danh tính dự án/cửa hàng vẫn có trong JSON.
show_store_namebooleanluôn luônMerchant 5.6.0+: hiển thị tên phần đầu. Cả hai mặc định true. Danh tính dự án/cửa hàng vẫn có trong JSON.
featured_chains[]arrayluôn luônTùy chọn có thứ tự, chỉ áp dụng cho phương thức đã có trong hóa đơn. Bỏ qua phương thức thiếu hoặc bị tắt.
featured_asset_ids[]arrayluôn luônTùy chọn có thứ tự, chỉ áp dụng cho phương thức đã có trong hóa đơn. Bỏ qua phương thức thiếu hoặc bị tắt.
default_asset_idUUID | nullluôn luônPhương thức ban đầu được gợi ý. Tùy chọn khách hàng được ghi nhớ hợp lệ hoặc phương thức đã nhận tiền được ưu tiên.
messagesobjectluôn luôn
Văn bản thuần cho en, de, es, pt-BR, it, ru, zh-CN, fr, ko và ja, theo khóa waiting, confirming, paid, underpaid và expired. Dùng tiếng Anh dự phòng khi thiếu thông báo nhà bán hàng. Chỉ bổ sung; không bao giờ thay trạng thái thực. Nội dung do nhà bán hàng viết không được tự dịch.Chi tiết
Văn bản thuần cho en, de, es, pt-BR, it, ru, zh-CN, fr, ko và ja, theo khóa waiting, confirming, paid, underpaid và expired. Dùng tiếng Anh dự phòng khi thiếu thông báo nhà bán hàng. Chỉ bổ sung; không bao giờ thay trạng thái thực. Nội dung do nhà bán hàng viết không được tự dịch.
support_emailstringluôn luônThông tin liên hệ và liên kết HTTPS tùy chọn, không có thông tin xác thực trong URL. Liên kết ngoài mở trong cửa sổ mới.
support_urlstringluôn luônThông tin liên hệ và liên kết HTTPS tùy chọn, không có thông tin xác thực trong URL. Liên kết ngoài mở trong cửa sổ mới.
terms_urlstringluôn luônThông tin liên hệ và liên kết HTTPS tùy chọn, không có thông tin xác thực trong URL. Liên kết ngoài mở trong cửa sổ mới.
privacy_urlstringluôn luônThông tin liên hệ và liên kết HTTPS tùy chọn, không có thông tin xác thực trong URL. Liên kết ngoài mở trong cửa sổ mới.
return_button_textstringluôn luônChỉ nhãn tùy chọn. Đích thành công/hủy và chính sách chuyển hướng vẫn thuộc hóa đơn.
show_return_buttonbooleanluôn luônHiển thị nút quay lại/hủy thủ công; mặc định true. Áp dụng cho trạng thái hoạt động và kết thúc, không áp dụng cho chuyển hướng thành công tự động. Có từ merchant 8.1.4.
preview_methods[]arraypayment_methods[]arrayGhi chú sử dụng
- Không chấp nhận hay cần token bearer.
- Không trả hóa đơn, đích nhận, ví, giao dịch, IPN, webhook hay metadata nhà bán hàng.
- Dùng bảng điều khiển có xác thực để lấy đúng liên kết xem trước trên tên miền thanh toán.
Lỗi
GETHình ảnh trang thanh toán của cửa hàng/checkout-api/invoices/{invoice_id}/appearance-images/{kind}/{revision}/image.pngCông khai
Trả logo hoặc favicon cửa hàng đã chuẩn hóa thuộc hóa đơn này. Dùng URL appearance.images từ dữ liệu thanh toán.
Xác thực & header
Công khai
Tham số đường dẫn
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png" \
--output 'store-logo.png'// Node.js 18+ · run on your server, never in browser code.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png", {
method: "GET",
headers: {},
redirect: "error",
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
await writeFile("store-logo.png", Buffer.from(await response.arrayBuffer()));<?php
// PHP 8+ with the cURL extension; run on your server.
$ch = curl_init("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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"); }
file_put_contents("store-logo.png", $response);# Python 3 · standard library; run on your server.
import json
from pathlib import Path
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png",
method="GET", headers=headers)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
Path("store-logo.png").write_bytes(response.read())Phản hồi 200 image/png
Phản hồi ví dụ
(binary PNG response)Ghi chú sử dụng
- Dùng appearance.images từ JSON thanh toán. Ảnh hóa đơn đóng băng tiếp tục hoạt động sau khi cửa hàng nguồn thay hoặc xóa tệp tải lên. Ảnh bị xóa rõ ràng, sai hóa đơn, sai loại và phiên bản không xác định trả 404; bản chụp không bao giờ dùng ảnh cửa hàng hiện tại làm dự phòng.
- Không có ghi đè hóa đơn thì dùng ảnh cửa hàng hiệu lực hiện tại, và phiên bản bị thay/xóa trả 404. Chỉ PNG, nosniff và lưu đệm riêng tư.
- Tải ảnh cửa hàng trong bảng điều khiển có xác thực chấp nhận PNG, JPEG hoặc WebP có giới hạn; không bao giờ SVG, HTML hay URL ảnh từ xa.
Lỗi
GETHình ảnh xem trước cửa hàng/checkout-api/previews/{project_id}/stores/{store_id}/appearance-images/{kind}/{revision}/image.pngCông khai
Chỉ trả ảnh xem trước đã chuẩn hóa khi dự án, cửa hàng, loại và phiên bản hiện tại khớp.
Xác thực & header
Công khai
Tham số đường dẫn
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png" \
--output 'store-preview-logo.png'// Node.js 18+ · run on your server, never in browser code.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png", {
method: "GET",
headers: {},
redirect: "error",
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
await writeFile("store-preview-logo.png", Buffer.from(await response.arrayBuffer()));<?php
// PHP 8+ with the cURL extension; run on your server.
$ch = curl_init("https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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"); }
file_put_contents("store-preview-logo.png", $response);# Python 3 · standard library; run on your server.
import json
from pathlib import Path
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/appearance-images/logo_light/YOUR_IMAGE_REVISION/image.png",
method="GET", headers=headers)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
Path("store-preview-logo.png").write_bytes(response.read())Phản hồi 200 image/png
Phản hồi ví dụ
(binary PNG response)Ghi chú sử dụng
- Dùng appearance.images từ dữ liệu xem trước. ID không xác định hoặc không khớp trả 404. Không cung cấp thông tin ví hay thanh toán.
Lỗi
GETLogo xem trước có phiên bản/checkout-api/previews/{project_id}/logo/{revision}/image.pngCông khai
Chỉ trả logo dự án đã chuẩn hóa khi dự án và phiên bản logo an toàn cho bộ nhớ đệm khớp. Dùng project.logo_url từ dữ liệu xem trước thay vì tự dựng URL này.
Xác thực & header
Công khai
Tham số đường dẫn
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID/logo/YOUR_LOGO_REVISION/image.png" \
--output 'checkout-preview-logo.png'// Node.js 18+ · run on your server, never in browser code.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID/logo/YOUR_LOGO_REVISION/image.png", {
method: "GET",
headers: {},
redirect: "error",
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
await writeFile("checkout-preview-logo.png", Buffer.from(await response.arrayBuffer()));<?php
// PHP 8+ with the cURL extension; run on your server.
$ch = curl_init("https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID/logo/YOUR_LOGO_REVISION/image.png");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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"); }
file_put_contents("checkout-preview-logo.png", $response);# Python 3 · standard library; run on your server.
import json
from pathlib import Path
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://pay.example.com/checkout-api/previews/YOUR_PROJECT_ID/logo/YOUR_LOGO_REVISION/image.png",
method="GET", headers=headers)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
Path("checkout-preview-logo.png").write_bytes(response.read())Phản hồi 200 image/png
Phản hồi ví dụ
(binary PNG response)Ghi chú sử dụng
- Dự án không xác định và phiên bản logo cũ trả invoice_not_found mà không tiết lộ thành phần nào thiếu.
- Hình ảnh có phiên bản được trả thành công là bất biến và có thể lưu đệm.
Lỗi
GETHình ảnh QR thanh toán/checkout-api/invoices/{invoice_id}/payment-methods/{intent_id}/qr.svgCông khai
Tạo QR SVG 512×512 cho payload thanh toán chính xác theo chuỗi của phương thức thanh toán hóa đơn.
Xác thực & header
Công khai
Tham số đường dẫn
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/payment-methods/YOUR_INTENT_ID/qr.svg" \
--output 'payment-qr.svg'// Node.js 18+ · run on your server, never in browser code.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/payment-methods/YOUR_INTENT_ID/qr.svg", {
method: "GET",
headers: {},
redirect: "error",
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
await writeFile("payment-qr.svg", Buffer.from(await response.arrayBuffer()));<?php
// PHP 8+ with the cURL extension; run on your server.
$ch = curl_init("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/payment-methods/YOUR_INTENT_ID/qr.svg");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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"); }
file_put_contents("payment-qr.svg", $response);# Python 3 · standard library; run on your server.
import json
from pathlib import Path
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/payment-methods/YOUR_INTENT_ID/qr.svg",
method="GET", headers=headers)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
Path("payment-qr.svg").write_bytes(response.read())Phản hồi 200 image/svg+xml
Phản hồi ví dụ
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">…</svg>Ghi chú sử dụng
- Không cần token bearer.
- Dùng qr_url có phiên bản theo trình tự và phần còn lại do JSON thanh toán trả; SVG là riêng tư và no-store.
- Sau thanh toán một phần, yêu cầu đúng số tiền còn lại và giữ khóa vào tài sản đó.
- Trả 409 sau hết hạn, hoàn tất hoặc khi phương thức khác đang hoạt động; trả payment_qr_unavailable (422) nếu yêu cầu quá lớn để mã hóa.
Lỗi
GETLogo trang thanh toán có phiên bản/checkout-api/invoices/{invoice_id}/logo/{revision}/image.pngCông khai
Chỉ trả logo thanh toán dự án đã chuẩn hóa khi hóa đơn và phiên bản logo hiện tại khớp. Nên dùng project.logo_url được JSON thanh toán trả thay vì tự dựng tuyến này.
Xác thực & header
Công khai
Tham số đường dẫn
Yêu cầu
curl --fail-with-body --max-time 30 \
--request GET \
--url "https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/logo/YOUR_LOGO_REVISION/image.png" \
--output 'checkout-logo.png'// Node.js 18+ · run on your server, never in browser code.
import { writeFile } from "node:fs/promises";
const response = await fetch("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/logo/YOUR_LOGO_REVISION/image.png", {
method: "GET",
headers: {},
redirect: "error",
signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
await writeFile("checkout-logo.png", Buffer.from(await response.arrayBuffer()));<?php
// PHP 8+ with the cURL extension; run on your server.
$ch = curl_init("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/logo/YOUR_LOGO_REVISION/image.png");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [],
]);
$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"); }
file_put_contents("checkout-logo.png", $response);# Python 3 · standard library; run on your server.
import json
from pathlib import Path
from urllib.request import Request, build_opener, HTTPRedirectHandler
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
headers = {}
request = Request("https://pay.example.com/checkout-api/invoices/YOUR_PUBLIC_INVOICE_ID/logo/YOUR_LOGO_REVISION/image.png",
method="GET", headers=headers)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
Path("checkout-logo.png").write_bytes(response.read())Phản hồi 200 image/png
Phản hồi ví dụ
(binary PNG response)Ghi chú sử dụng
- Không cần token bearer.
- Thời hạn lưu đệm công khai một năm với immutable vì phiên bản là trạng thái định địa chỉ theo nội dung.
- Phiên bản không xác định/không khớp trả invoice_not_found.
Lỗi
Tài liệu tham chiếu cho Wholly Crypto 8.3.2. Với phiên bản đã cài, mở Cài đặt → Truy cập API → Tài liệu trong bảng điều khiển. Xem bản phát hành.