DOKUMENTASI PENGEMBANG
Dokumentasi API
Integrasikan faktur, checkout, dan notifikasi pembayaran.
Hasil pencarian
Tidak ada hasil. Coba nama endpoint, kolom, atau panduan.
Panduan cepat
Buat faktur pertamamu.
- Siapkan toko
Aktifkan metode pembayarannya, konfigurasikan penyedia, dan cadangkan dompet proyek.
- Buat kredensial API
Di Pengaturan → Akses API konsolmu, pilih baca/tulis dan tetapkan proyek.
- Kirim permintaan
Gunakan host API-mu dan salin ID proyek dan tokomu. Kirim jumlah desimal sebagai string.
- Buka checkout
Alihkan ke
links.checkoutdari respons. Verifikasi penyelesaian sebelum memenuhi pesanan.
: "${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))Contoh menggunakan placeholder dan tidak mengirim permintaan dari halaman ini. Lihat setiap kolom faktur dan format respons →
ID proyek & toko
Tempat menemukan YOUR_PROJECT_ID dan YOUR_STORE_ID.
Gunakan UUID dari konsolmu, bukan nama proyek atau toko maupun pengenal yang mudah dibacanya.
| Placeholder | Tempat menemukannya | Digunakan untuk |
|---|---|---|
| YOUR_PROJECT_ID | Proyek → Pengaturan → ID API → ID API Proyek → Salin. Juga ditampilkan di tab Dasar toko. | Permintaan tingkat proyek dan tingkat toko. |
| YOUR_STORE_ID | Proyek → Toko → pilih toko → Dasar → ID API → ID API Toko → Salin. | Pembuatan faktur dan permintaan metode pembayaran toko. |
- Pembuatan faktur memerlukan kedua ID, bahkan untuk toko bawaan. Toko harus menjadi bagian dari proyek tersebut, dan kredensial API harus memiliki akses ke proyek.
- Pembuatan, daftar, detail faktur, dan checkout mengembalikan invoice_id: UUID yang sama dengan yang dikirim dalam IPN/webhook. Gunakan dalam path faktur, bukan id internal atau order_id. Sejak merchant 4.0.0, kolom respons public_id lama dihapus; perbarui integrasi sebelum memperbarui versi.
- REST API tidak menyediakan rute daftar proyek/toko. Salin ID di konsol, atau gunakan alat MCP list_projects dan list_stores dengan cakupan terbatas di merchant 5.0.0+.
- Toko → Dasar → Domain toko memilih nama host merchant, pay, dan API yang aktif. Tautan checkout yang dikembalikan dan tautan callback baru mengutamakan toko tersebut, lalu toko bawaan, lalu pengaturan bawaan sistem. Nama yang dihentikan atau belum diaktifkan tidak pernah dipilih. Konfigurasikan SDK dengan nama host API pilihanmu; mengubah preferensi tidak mengalihkan alias aktif lainnya.
Autentikasi & cakupan
Simpan kredensial di servermu dan berikan hanya akses yang diperlukan.
| Host bawaan | Tujuan |
|---|---|
| merchant.example.com | Konsol merchant dan Pengaturan |
| pay.example.com | Checkout pelanggan |
| api.example.com | Permintaan API merchant |
Ganti example.com dengan domainmu. Instalasi yang ada mempertahankan nama yang dikonfigurasi; kelola alias di Pengaturan → Sistem.
Authorization: Bearer YOUR_MERCHANT_API_TOKEN| Pengaturan | Cara kerjanya |
|---|---|
| Tingkat akses | Kredensial hanya baca bisa menampilkan daftar dan mengambil data. Kredensial baca/tulis juga bisa membuat faktur dan memperbarui kebijakan aset yang didokumentasikan. |
| Proyek | Tetapkan proyek yang boleh diakses kredensial. ID toko dan faktur harus milik proyek yang ditetapkan. |
| Pembatasan IP | Jika mau, izinkan alamat egress IPv4 atau IPv6 publik secara persis di Pengaturan → Akses API. |
| Penyimpanan kredensial | Simpan token dalam konfigurasi backend-mu. Jangan pernah menyertakan kredensial bearer dalam browser atau tautan checkout. |
Rute checkout publik menggunakan ID publik faktur dan hanya menampilkan data yang aman untuk checkout. Sesi konsol dan kontrol administratif terpisah dari kredensial API merchant.
Aset & dompet
Pilih metode pembayaran secara terpisah untuk setiap toko.
- Baca aset pembayaran proyek dan kesiapannya.
- Aktifkan blockchain native dan konfigurasikan dompet serta penyedianya.
- Jelajahi kandidat token dan verifikasi kontrak atau mint sebelum mengaktifkan token.
- Pilih urutan metode pembayarantoko. Faktur baru menggunakan pilihan yang siap digunakan.
Token berbagi dompet blockchain native-nya. Saldo dompet mengembalikan jumlah atomik presisi dan nilai fiat sebagai referensi. Gunakan kolom kesiapan yang dikembalikan untuk menentukan metode yang bisa menerima pembayaran.
Token ERC-20 terverifikasi menggunakan jaringan EVM yang didukung; token SPL terverifikasi menggunakan Solana. Metode pembayaran native tersedia di 30 jaringan terintegrasi. Monero menggunakan koneksi dompet hanya lihat eksternal yang terikat ke proyek.
API penerimaan dan cakupan native/token
| Jalur pembayaran | Dukungan | Bukti | Persyaratan |
|---|---|---|---|
| Jalur pembayaran native | didukung | Dipindai per transaksi | BTC, SOL, ETH (Ethereum/Base/Arbitrum/OP), BNB, HYPE, AVAX, dan POL; output Bitcoin, transaksi/receipt EVM kanonis, serta transfer Solana yang diparsing menyediakan bukti faktur. |
| Jalur token ERC-20 | didukung | Dipindai per transaksi | Ethereum, Base, BNB Chain, HyperEVM, Avalanche, Polygon, Arbitrum, dan Optimism memerlukan verifikasi on-chain; log Transfer yang diindeks menyediakan atribusi pembayaran. |
| Jalur token SPL | didukung | Dipindai per transaksi | Kandidat Solana memerlukan verifikasi mainnet dan mint; perubahan saldo token yang presisi dalam transaksi yang diparsing menyediakan atribusi pembayaran. |
| Jalur native UTXO tambahan | didukung | Dipindai per transaksi | BCH/LTC/DOGE menggunakan Esplora; BCH/DOGE juga menerima Bitcore, LTC/DOGE/DASH menerima BlockCypher, Dash menerima Insight, dan ZEC transparan menerima zcash-explorer. Semuanya juga menerima blok node-rpc kompatibel Core yang disimpan lengkap. Mode mentah memerlukan 1–48 konfirmasi, bukan deteksi mempool. Zcash terlindung tidak didukung. |
| Jalur native akun terindeks | didukung | Dipindai per transaksi | TRON menggunakan tron-indexer atau node-rpc tersolidifikasi; XRP menggunakan xrpl-jsonrpc; Stellar menggunakan stellar-horizon atau buku besar node-rpc Stellar yang disimpan; Cosmos Hub menggunakan cometbft-jsonrpc; Algorand menggunakan algorand-indexer atau node-rpc algod; Hedera memerlukan hedera-mirror, bukan relay EVM. |
| Jalur pembayaran buku besar native | didukung | Dipindai per transaksi | Aptos menggunakan aptos-rest; Sui menggunakan sui-graphql; NEAR menggunakan near-jsonrpc; Kaspa menggunakan kaspa-rest. Polkadot Asset Hub menerima substrate-rest atau node-rpc final yang memahami metadata; Tezos menerima tezos-tzkt atau operasi node-rpc Octez lengkap. Hanya penerimaan native; retensi arsip diperlukan untuk faktur lama. |
| Jalur native Cardano dan TON | didukung | Dipindai per transaksi | Cardano memerlukan cardano-koios dan TON memerlukan toncenter-v3. Tag XRP, ID memo Stellar, dan komentar faktur TON dikembalikan sebagai destination_tag dan harus dikirim persis. |
| Integritas penyelesaian | didukung | Verifikasi independen | Secara bawaan, penyelesaian final memerlukan dua penyedia independen yang sepakat pada transaksi/peristiwa, jumlah, blok atau slot kanonis, dan finalitas secara persis. Jendela mentah dan EVM bersama juga memverifikasi cakupan lengkap. Administrator boleh secara eksplisit memilih satu penyedia tepercaya untuk blockchain; ini menghapus pemeriksaan silang independen, bukan pemeriksaan identitas, kelengkapan, atau finalitas. |
| Jalur native Monero | didukung | RPC dompet hanya lihat yang terikat ke proyek | Satu wallet-RPC hanya pantau eksternal khusus di balik gateway HTTPS yang membatasi metode yang diizinkan membuat subalamat account-0. Ambang daemon mainnet yang dikonfigurasi (bawaan 2 sumber independen, opsional 1) menyediakan bukti penyelesaian. --restricted-rpc native tidak kompatibel dengan create_address; cadangan dompet dan ketiadaan spend key secara eksplisit dinyatakan oleh operator, sementara tidak ada materi kunci yang dikirim ke Wholly Crypto. |
Saldo bursa dan pilihan sweep dompet-atau-bursa per aset tersedia di konsol, bukan melalui API publik v1. Lihat penyiapan bursa.
Siklus hidup faktur
Bukti pembayaran, penyelesaian, dan pemenuhan pesanan.
| Status | Arti |
|---|---|
| new | Menunggu pembayaran |
| processing | Pembayaran teramati; jumlah yang diterima atau finalitas masih tertunda |
| settled | Diterima berdasarkan kebijakan penyelesaian faktur, atau secara manual |
| expired | Tenggat berlalu; pemantauan pembayaran terlambat dapat berlanjut |
| invalid | Pembayaran tidak bisa diterima secara otomatis |
| cancelled | Dibatalkan; hanya rekonsiliasi eksplisit yang bisa membukanya kembali |
amount_status mencatat none, partial, paid atau overpaid. timing_status membedakan pembayaran tepat waktu dan terlambat. Aturan toko menentukan konfirmasi yang diperlukan dan toleransi kekurangan pembayaran yang diterima.
Gunakan invoice_id faktur dengan rute detail faktur. Pengalihan checkout saja bukan bukti penyelesaian. Tinjau pengecualian melalui rekonsiliasi.
Percobaan ulang yang aman
Pembuatan faktur memerlukan Idempotency-Key. Setelah batas waktu terlampaui, coba lagi dengan kredensial, kunci, dan body permintaan yang sama persis. Gunakan kunci baru hanya untuk faktur baru.
Pemindaian pembayaran EVM
Penemuan blok native dan ERC-20 bersama mengelompokkan faktur terbaru secara terpisah dari pekerjaan pengejaran riwayat lama. Setiap faktur mempertahankan kursor riwayat persistennya. Kueri token menggunakan paling banyak 100 blok per permintaan dan menyusut untuk batas penyedia yang lebih ketat. Dua penyedia independen memverifikasi setiap jendela secara bawaan. Pengaturan → Koneksi blockchain → Detail bisa memilih satu sumber tepercaya untuk blockchain, tanpa pemeriksaan silang independen; pemeriksaan transaksi kanonis, jumlah, dan konfirmasi tetap berlaku. Detail koneksi membedakan keterlambatan pemindai, pembatasan riwayat, dan masa tunggu kuota dari kesehatan node dasar. Kapasitas RPC publik tidak dijamin.
IPN & webhook
Terima dan verifikasi peristiwa pembayaran.
IPN menerima setiap peristiwa faktur yang dihasilkan pada ipn_url efektif faktur. Webhook hanya menerima peristiwa yang dipilih untuk setiap endpoint toko yang diaktifkan. Keduanya mengirim snapshot JSON yang sama melalui POST; keduanya independen, sehingga mengaktifkan keduanya bisa memberi tahu aplikasimu dua kali.
Tetapkan ipn_url saat membuat faktur, atau warisi pengaturan bawaan toko. IPN menggunakan rahasia Toko → IPN ; setiap endpoint Toko → Webhook memiliki rahasianya sendiri. Keduanya bukan kunci API-mu.
Kapan aku harus memenuhi pesanan?
Untuk penanganan berbasis peristiwa, gunakan event_type = invoice.settled bersama status = settled untuk memicu pemeriksaan pesanan. Verifikasi faktur terkini dan penuhi setiap pesanan hanya sekali.
status adalah keadaan faktur saat peristiwa dibuat. event_type menjelaskan apa yang terjadi. payment.received bisa membawa processing atau settled; ini tidak berarti pembayaran kedua dan bukan sinyal pemenuhan yang independen.
Peristiwa dan status apa yang dikirim?
| Peristiwa dalam pengaturan/riwayat | Status body | Arti |
|---|---|---|
| invoice.created | new | Faktur dibuat dan menunggu pembayaran. Juga digunakan saat pembukaan ulang terkontrol mengembalikan faktur ke new. |
| payment.received | Resulting invoice status | Pembayaran dicatat atau jumlah yang diterima bertambah. Biasanya processing atau settled; peristiwa ini saja bukan bukti penyelesaian. |
| invoice.processing | processing | Pembayaran terdeteksi, tetapi jumlah yang diterima atau finalitas yang diperlukan belum terpenuhi. Pembayaran parsial termasuk. |
| invoice.settled | settled | Kebijakan penyelesaian terpenuhi, atau diterima secara manual. Periksa resolution dan pesananmu sebelum pemenuhan. |
| invoice.expired | expired | Tenggat pembayaran berlalu. Pembayaran terlambat masih bisa mengubah status selama pemantauan berlanjut. |
| invoice.invalid | invalid | Tidak bisa diterima otomatis, bukti pembayaran hilang, atau merchant menolaknya. Tinjau faktur. |
| invoice.cancelled | cancelled | Faktur dibatalkan. Jangan penuhi pesanan; pembatalan tidak mengembalikan pembayaran on-chain. |
Mengapa Ethereum dan Solana bisa mengirim alur peristiwa berbeda
Konfirmasi datang belakangan (contoh Ethereum)
| Urutan | event_type | status |
|---|---|---|
| 1 | invoice.created | new |
| 2 | payment.received | processing |
| 2 | invoice.processing | processing |
| 3 | invoice.settled | settled |
Sudah final saat terdeteksi (contoh Solana)
| Urutan | event_type | status |
|---|---|---|
| 1 | invoice.created | new |
| 2 | payment.received | settled |
| 2 | invoice.settled | settled |
Ini menampilkan pembuatan peristiwa, bukan urutan pengiriman yang dijamin. Kedua alur bisa terjadi pada blockchain lain bergantung pada waktu deteksi dan kebijakan penyelesaian. Jangan mensyaratkan peristiwa processing sebelum settled.
Penuhi satu kali: contoh penerima dan perlindungan duplikasi
| Pendekatan | Cara menanganinya |
|---|---|
| Penerima berbasis peristiwa | Pertahankan peristiwa berbeda berdasarkan event_id bertanda tangan, lalu pilih invoice.settled dengan status = settled. Jangan buang peristiwa ini karena payment.received dengan sequence yang sama datang lebih dahulu. |
| Kotak masuk status pesanan SDK | Contoh penerima PHP, Python, dan Node yang disediakan menggabungkan proyek + invoice_id + sequence. Proses status yang disimpan terlepas dari event_type, ambil faktur terkini, dan penuhi satu kali jika settled. Jangan tambahkan filter khusus invoice.settled setelah penggabungan ini. |
Percobaan ulang mempertahankan event_id dan body asli. Peristiwa berbeda bisa berbagi sequence tetapi memiliki nilai event_id berbeda. Deduplikasi pengiriman berdasarkan event_id bertanda tangan untuk penanganan berbasis peristiwa; lindungi pemenuhan secara independen berdasarkan instalasi/proyek yang dikonfigurasi + invoice_id dan pesananmu. Penyelesaian ulang berikutnya tidak boleh mengkreditkan pesanan dua kali.
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.Pseudocode, bukan penerima siap pakai.
Semua status faktur dan pengecualian pembayaran
| Kolom | Nilai | Arti |
|---|---|---|
| status | new, processing, settled, expired, invalid, cancelled | Status faktur saat peristiwa dibuat; belum tentu status terkini saat dikirim. |
| amount_status | none, partial, paid, overpaid | Jumlah diterima, termasuk toleransi yang disetujui. paid bukan finalitas konfirmasi. |
| timing_status | on_time, late | Apakah pembayaran memenuhi tenggat faktur. |
| resolution | automatic, manually_settled, manually_invalidated | Apakah aturan normal atau penerimaan/penolakan manual menentukan hasilnya. |
| requires_review | false, true | Petunjuk pengecualian, bukan status faktur lain atau izin otomatis untuk memenuhi pesanan/mengembalikan dana. |
| Situasi | Penanganan |
|---|---|
| Kekurangan pembayaran / toleransi | Dalam aturan otomatis, partial tidak menyelesaikan faktur. paid bisa mencakup kekurangan yang diterima, tetapi finalitas tetap diperlukan. Gunakan status faktur, bukan perbandingan jumlah saja. |
| Kelebihan pembayaran | overpaid bisa bersamaan dengan settled dan requires_review = true. Terapkan kebijakan kelebihan pembayaranmu; jangan pernah mengkreditkan pesanan dua kali atau otomatis mengembalikan dana ke alamat yang belum diverifikasi. |
| Pembayaran terlambat | expired bisa berubah kemudian selama pemantauan berlanjut. timing_status = late menandai perlunya tinjauan; jangan otomatis membuka ulang atau mengirim pesanan yang dibatalkan. |
| Penerimaan manual | invoice.settled bisa memiliki resolution = manually_settled tanpa dana on-chain yang memenuhi syarat. Tentukan apakah integrasimu menerima pengesampingan ini; kolom ringkasan pembayaran mungkin null. |
| Reorg / pembatalan validitas | Revisi yang lebih baru bisa membatalkan validitas bukti pembayaran sebelumnya. Ambil ulang status terkini dan tangani pembalikan melalui rekonsiliasi. Jangan mengabaikannya hanya karena pesanan pernah diselesaikan. |
| Nol konfirmasi / jumlah nol | Penyelesaian tanpa konfirmasi bisa terjadi saat deteksi dan membawa risiko reorg. Faktur bernilai nol yang secara eksplisit diizinkan diselesaikan tanpa pembayaran. Keduanya tidak memerlukan peristiwa payment.received terlebih dahulu. |
Gunakan status = settled untuk pemenuhan, bukan amount_status = paid dan bukan pengalihan checkout. Dengan nol konfirmasi yang diperlukan, penyelesaian bisa terjadi saat deteksi; ini membawa risiko reorg.
Kurang bayar adalah amount_status = partial; lebih bayar adalah overpaid. paid berarti minimum yang diterima, termasuk toleransi kekurangan pembayaran faktur, telah tiba. Ini adalah status jumlah, bukan status faktur. late adalah timing_status, bukan peristiwa terpisah.
Alur umum adalah new → processing → settled, tetapi status perantara bisa dilewati. Faktur bernilai nol yang secara eksplisit diizinkan diselesaikan tanpa pembayaran dan mempertahankan amount_status = none. Penerimaan manual ditandai manually_settled.
Callback adalah snapshot yang tidak dapat diubah, bukan respons status langsung. Callback bisa tiba terlambat, tidak berurutan, atau lebih dari sekali. Peristiwa pembayaran dan status bisa berbagi sequence faktur serta kolom status faktur yang sama, tetapi memiliki nilai event_id dan event_type bertanda tangan yang berbeda. Jumlah konfirmasi tidak menjamin callback untuk setiap blok.
Yang kamu terima
{
"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 adalah total faktur asli. payment_info menjelaskan transfer kripto yang teramati, jumlah yang masih kurang, dan kurs terkunci. Versi 2 juga menandatangani nama peristiwa, ID peristiwa, serta cakupan proyek/toko.
Semua kolom callback dan data faktur tambahan
| Kolom | Tipe | Arti |
|---|---|---|
| invoice_id | UUID | UUID faktur publik, digunakan oleh rute detail faktur terautentikasi |
| status | string | Snapshot status faktur: new, processing, settled, expired, invalid, cancelled |
| amount_status | string | none, partial, paid, atau overpaid; paid mencakup toleransi kekurangan pembayaran yang diterima, bukan finalitas konfirmasi |
| timing_status | string | on_time atau late |
| resolution | string | automatic, manually_settled, atau manually_invalidated |
| sequence | integer | Revisi faktur yang meningkat; peristiwa berbeda bisa berbagi satu revisi. Bandingkan tanpa kehilangan presisi bilangan bulat |
| amount | decimal string | Total faktur asli, bukan jumlah kripto yang diterima; pertahankan presisi desimal |
| currency | string | Mata uang amount, mis. EUR untuk faktur EUR yang dibayar dengan USDC |
| order_id | string | null | Referensi pesanan merchant |
| payload_version | integer | 2 untuk peristiwa baru yang dihasilkan versi 4.1.0+; tidak ada pada peristiwa lama yang tersimpan |
| event_id | UUID | Identitas peristiwa bertanda tangan, tetap sama pada percobaan ulang dan pengiriman ulang manual |
| event_type | string | Salah satu dari tujuh peristiwa langganan |
| occurred_at | timestamp | Waktu peristiwa yang tidak dapat diubah ini dibuat, bukan waktu pengiriman |
| project_id | UUID | Cakupan proyek merchant; cocokkan dengan penerima yang dikonfigurasi |
| store_id | UUID | Cakupan toko merchant; cocokkan dengan penerima yang dikonfigurasi |
| description | string | null | Deskripsi faktur asli |
| string | null | Email pelanggan opsional saat peristiwa dibuat | |
| customer | object | Kolom metadata pelanggan opsional yang dikenali; tanpa data pribadi yang ditebak atau diperkaya |
| metadata | object | Metadata merchant asli sebagaimana adanya saat peristiwa dibuat |
| created_at | timestamp | Waktu pembuatan faktur |
| updated_at | timestamp | Waktu pembaruan status faktur |
| expires_at | timestamp | Tenggat pembayaran faktur |
| monitoring_expires_at | timestamp | Tenggat pemantauan pembayaran terlambat |
| settled_at | timestamp | null | Waktu penyelesaian |
| paid_chain | string | null | 4.1.2+: slug blockchain dari metode penyelesaian yang terbukti, mis. ethereum; null tanpa penyelesaian memenuhi syarat yang tersimpan |
| paid_asset | string | null | 4.1.2+: ticker koin native atau token, mis. BTC, ETH, atau USDC; label tampilan, bukan identitas aset unik |
| paid_asset_amount | decimal string | null | 5.0.1+: seluruh jumlah terkunci yang diminta dalam unit paid_asset, sebelum mengurangi toleransi; disimpan saat penyelesaian |
| paid_asset_amount_received | decimal string | null | 5.0.1+: total jumlah valid yang diterima untuk metode pemenang saat penyelesaian, termasuk kekurangan/kelebihan yang diterima; dibekukan, bukan saldo langsung |
| paid_payment_method_id | UUID | null | 4.1.2+: ID intent penyelesaian; cocok dengan payment_info.methods[].payment_method_id dan jaringan/kontraknya secara persis |
| settlement_exchange_rate | object | null | 4.1.2+: snapshot pasar sebelum spread yang disimpan saat penyelesaian, dengan unit, mata uang, stempel waktu sumber, dan penanda kualitas eksplisit; harganya tidak pernah dihitung ulang saat pengiriman |
| cancelled_at | timestamp | null | Waktu pembatalan |
| exchange_rate_spread_percent | decimal string | Spread terkunci, bukan pengaturan bawaan toko saat ini |
| underpayment_tolerance_percent | decimal string | Toleransi faktur terkunci; setiap metode juga melaporkan toleransi efektifnya |
| reason_code | string | null | Alasan transisi status yang dapat dibaca mesin |
| requires_review | boolean | Petunjuk pengecualian pembayaran; bukan izin memenuhi pesanan atau mengembalikan dana secara otomatis |
| links | object | URL checkout, faktur terautentikasi, dan pembayaran saat peristiwa dibuat. Preferensi domain Toko → Dasar berlaku, lalu toko bawaan, lalu domain utama global; hanya domain aktif yang sesuai perannya yang digunakan. Percobaan ulang mempertahankan tautan asli bertanda tangan; null jika tidak ada catatan host aktif. |
| payment_info | object | Metode yang benar-benar teramati, jumlah presisi, kuotasi terkunci, snapshot pasar referensi, dan observasi pembayaran terbatas; lihat kelompok kolom di bawah |
Ringkasan penyelesaian: settlement_exchange_rate
| Kolom | Tipe | Arti |
|---|---|---|
| rate / units / currency / symbol | strings | Unit aset sebelum spread per satu unit mata uang faktur. String desimal, bukan jumlah pembayaran atau perdagangan yang dieksekusi. |
| observed_at / as_of | timestamps | Waktu pencatatan penyelesaian / stempel waktu sumber yang lebih lama. Jangan menganggap data cache sebagai tick langsung. |
| pricing_provider / asset_provider / pricing_fetched_at / asset_fetched_at | strings / timestamps | Sumber harga fiat dan aset beserta waktu pengambilannya, disimpan saat penyelesaian. |
| stale / is_fixed / uses_reference_proxy / reference_currency | booleans / string | Penanda kualitas yang sama seperti market_rate_at_event. Harga proyek tetap diberi label; mata uang referensi adalah USD. |
| Missing snapshot or price | null | Tidak ada kurs historis yang ditebak. Sebelum penyelesaian, semua kolom ringkasan null; harga yang tidak tersedia saja tetap membiarkan pengenal paid_* yang terbukti tersedia. |
Metode pembayaran: payment_info
| Kolom | Tipe | Arti |
|---|---|---|
| active_payment_method_id | UUID | null | Metode teramati yang menang atau dipilih. Null sebelum deteksi atau setelah pembatalan validitas; tidak ada metode bawaan yang ditebak. |
| method_count / methods_truncated | integer / boolean | Total metode teramati dan apakah daftar methods tersemat tidak lengkap. |
| methods[] | object[] | Paling banyak delapan metode teramati, metode aktif lebih dahulu. Tanpa total lintas aset. |
| payment_method_id / payment_rail | UUID / string | Identitas intent faktur dan transport onchain atau lightning. |
| chain_slug / network / caip_network_id | string | Identitas jaringan. Selalu pasangkan identitas token dengan jaringannya. |
| asset_id / asset_key / caip_asset_id | UUID / string / nullable string | Identitas registri terverifikasi; simbol saja tidak unik. |
| asset_name / symbol / asset_kind | string | Nama tampilan aset, ticker, dan jenis native atau token. |
| contract_address / token_standard | string | null | Kontrak atau mint token serta standarnya; null untuk aset native. |
| asset_decimals | integer | Presisi atomik; BTC Lightning menggunakan 11. |
| destination_address / destination_tag | string | null | Alamat penerimaan publik dan memo/tag yang diperlukan. Alamat bernilai null untuk Lightning; tidak pernah berupa kunci privat. |
| status | string | Status metode: pending, partial, paid, overpaid, expired, atau invalid. Paid sendiri bukan penyelesaian faktur. |
| payment_count / payments_truncated / payments[] | integer / boolean / object[] | Total observasi dan lima yang terbaru atau lebih sedikit. Setiap observasi dijelaskan di bawah. |
| links.payments | HTTPS URL | null | Riwayat berhalaman yang terautentikasi untuk metode ini pada origin API yang dikonfigurasi. |
Jumlah presisi: methods[].amounts
| Kolom | Tipe | Arti |
|---|---|---|
| expected_amount | decimal string | Kuotasi terkunci penuh, setelah spread dan pembulatan ke atas. |
| received_amount / confirmed_amount | decimal strings | Dana valid yang terdeteksi / dana yang memenuhi kebijakan konfirmasi atau finalitas metode ini. |
| unconfirmed_amount | decimal string | max(received - confirmed, 0). Bukan jumlah tambahan untuk dikirim. |
| minimum_payment_amount | decimal string | Ambang yang diterima setelah toleransi. Bisa di bawah kuotasi penuh. |
| remaining_amount | decimal string | max(minimum accepted - received, 0). Dana tambahan yang diperlukan untuk mencapai ambang yang diterima, bukan progres konfirmasi. |
| remaining_to_full_amount | decimal string | max(full quote - received, 0), mengabaikan toleransi. |
| overpaid_amount | decimal string | max(received - full quote, 0). Tidak mengotorisasi pengembalian dana otomatis. |
| Every amount's *_atomic companion | integer string | Representasi unit terkecil yang presisi. Gunakan pustaka desimal atau bilangan bulat; jangan pernah menggunakan float atau JavaScript Number untuk uang. |
Kebijakan konfirmasi: methods[].acceptance
| Kolom | Tipe | Arti |
|---|---|---|
| finality_mode / required_confirmations | string / integer | Konfirmasi terkunci atau kebijakan finalized. Nol konfirmasi diizinkan secara eksplisit oleh kebijakan merchant, bukan finalitas jaringan universal. |
| observed_confirmations | integer | null | Minimum di antara observasi valid, bukan hanya transfer terbaru. Null untuk Lightning atau jika tidak ada observasi valid. |
| underpayment_tolerance_percent | decimal string | Toleransi metode efektif. Lightning menggunakan nol meski faktur memiliki toleransi on-chain bukan nol. |
Kurs: methods[].quote dan market_rate_at_event
| Kolom | Tipe | Arti |
|---|---|---|
| quote.effective_rate / units / currency / symbol | strings | Kurs asset_per_invoice_currency terkunci termasuk spread; mata uang dan simbol menyatakan arahnya secara eksplisit. |
| quote.exchange_rate_spread_percent / quote_expires_at | decimal string / timestamp | Spread terkunci dan tenggat kuotasi. Tidak pernah diganti dengan pengaturan toko saat ini. |
| quote.reference_rate / unrounded_payment_amount / rounding_adjustment | decimal string | null | Referensi sebelum spread, jumlah pembayaran sebelum pembulatan, dan penyesuaian ke atas dalam unit aset. |
| quote.pricing_provider / asset_provider / pricing_fetched_at / asset_fetched_at | string or timestamp | null | Sumber/waktu harga mata uang dan aset asli. Tanpa kunci API atau kredensial penyedia. |
| quote.provenance_available / rounding | boolean / string | False untuk faktur lama tanpa snapshot sumber tersimpan; pembulatan ke atas. |
| market_rate_at_event | object | null | Snapshot pasar dalam cache sebagai referensi saat peristiwa ini dibuat. Data yang tidak tersedia tetap null; tidak pernah mengubah jumlah faktur atau menunggu pengambilan melalui jaringan. |
| market_rate_at_event.rate / units / currency / symbol | strings | Kurs pasar sebelum spread, dengan arah eksplisit yang sama seperti quote. |
| market_rate_at_event.observed_at / as_of / pricing_fetched_at / asset_fetched_at | timestamps | Waktu snapshot peristiwa / waktu yang lebih lama dari dua sumber / waktu masing-masing sumber. |
| market_rate_at_event.pricing_provider / asset_provider | strings | Sumber mata uang dan aset dalam cache, termasuk harga token kustom yang dikonfigurasi. |
| market_rate_at_event.stale / is_fixed / uses_reference_proxy / reference_currency | booleans / string | Apakah cache usang, harga token tetap, atau referensi USD menggunakan stablecoin sebagai perantara. Mata uang referensi adalah USD. Status usang bersifat informatif, tidak pernah menjadi kuotasi baru. |
Catatan transfer: methods[].payments[] dan GET …/payments
| Kolom | Tipe | Arti |
|---|---|---|
| payment_id / payment_method_id | UUID | Identitas observasi / identitas intent induk. Gunakan payment_id untuk deduplikasi riwayat. |
| transaction_id / payment_hash / event_index | string | null / integer | Hash on-chain dan indeks transfer/log/output, atau hash Lightning. Lightning tidak memiliki transaksi atau tautan penjelajah. |
| payment_rail / chain_slug / network / asset_id / asset_key / caip_asset_id / symbol / asset_decimals | strings / UUID / integer | Pengenal aset dan jaringan yang sama dengan metode yang memuatnya. |
| amount / amount_atomic | decimal / integer strings | Nilai presisi transfer ini, tidak pernah berupa konversi fiat. |
| status / counts_towards_received | string / boolean | detected, confirming, dan final dihitung; reorged, replaced, dan invalid tidak. Pertahankan riwayat yang dibatalkan validitasnya untuk rekonsiliasi. |
| confirmations / block_height | integer | null | Data blok observasi; konfirmasi bernilai null untuk Lightning. |
| observed_at / chain_time / finalized_at | timestamp | null | Waktu pertama terlihat secara lokal, waktu blockchain tepercaya jika tersedia, dan waktu final sesuai kebijakan jika tercapai. |
| explorer_name / explorer_url | string | null | Referensi penjelajah blok publik yang divalidasi, jika didukung. |
Merchant 5.13.3 mengecualikan transfer pendanaan gas internal terverifikasi dari total pembayaran pelanggan, payment_info, API pembayaran faktur, batas pengembalian dana, dan peristiwa payment.received. Catatan blockchain/treasury-nya tetap tersedia untuk akuntansi dompet. Transfer biasa dan kelebihan pembayaran nyata tetap dihitung. Body callback bertanda tangan yang sudah ada tidak pernah ditulis ulang. Jika penyelesaian historis bergantung pada pendanaan internal alih-alih dana pelanggan, rekonsiliasi menerbitkan invoice.invalid dengan reason_code internal_gas_funding_excluded; tinjau, jangan memenuhi pesanan lagi.
Merchant 4.1.0 menambahkan payload_version 2 tanpa memindahkan atau mengubah sembilan kolom asli. Peristiwa yang sebelumnya masuk antrean mempertahankan body aslinya dan mungkin tidak memiliki payload_version. event_id, event_type, serta ID proyek/toko kini berada dalam body bertanda tangan; header peristiwa/pengiriman transport tetap tidak ditandatangani.
payment_info menjelaskan pembayaran yang teramati, bukan setiap opsi checkout yang ditawarkan. Sebelum deteksi, active_payment_method_id bernilai null dan methods kosong. Observasi reorged/invalid bisa tetap ada dalam methods meski metode aktif menjadi null. Jangan pernah menjumlahkan jumlah dari aset atau jaringan berbeda.
Semua jumlah, bilangan bulat atomik, kurs, dan persentase berupa string. received_amount mencakup dana valid yang menunggu konfirmasi; confirmed_amount memenuhi kebijakan finalitas metode tersebut. remaining_amount adalah max(minimum_payment_amount dikurangi received_amount, 0); remaining_to_full_amount adalah max(expected_amount dikurangi received_amount, 0). Contoh: 100 USDC diharapkan, 99 diterima, toleransi 1% berarti remaining_amount 0 dan remaining_to_full_amount 1. Finalitas tetap diperlukan.
quote adalah perhitungan faktur terkunci: unit aset per satu unit mata uang faktur. Spread diterapkan sebelum pembulatan ke atas. Gunakan expected_amount_atomic untuk perbandingan pembayaran presisi; kurs yang ditampilkan saja mungkin tidak bisa mereproduksi pembulatan ke atas. Faktur lama tanpa asal sumber tersimpan menampilkan kolom source/reference/rounding null dan provenance_available false, tidak pernah data hari ini yang disajikan sebagai kuotasi historis.
market_rate_at_event adalah data cache referensi sebelum spread, dibekukan saat peristiwa dibuat. Data ini memiliki waktu sumber, penanda stale, dan penanda perantara referensi; nilainya null jika tidak ada pasangan cache yang dapat digunakan. Permintaan kurs langsung tidak memblokir notifikasi, dan observasi pasar ini tidak pernah mengubah jumlah terutang. Token kustom berharga tetap diberi label is_fixed; token DEX menggunakan sumber khusus proyeknya, bukan token dengan simbol yang sama.
paid_chain, paid_asset, paid_payment_method_id, dan settlement_exchange_rate tingkat atas (4.1.2+) mengidentifikasi metode pemenang yang terbukti setelah penyelesaian, bukan opsi checkout yang dipilih atau penjumlahan metode berbeda. Sebelum penyelesaian, setelah pembatalan validitas, untuk penyelesaian lama tanpa snapshot, atau untuk penerimaan manual tanpa dana yang memenuhi finalitas kebijakan, kolom ringkasan bernilai null. Simbol adalah label tampilan: ikuti ID metode untuk identitas jaringan/aset/kontrak yang persis.
Merchant 5.0.1 menambahkan paid_asset_amount dan paid_asset_amount_received sebagai string desimal presisi dalam unit paid_asset; payload_version tetap 2. paid_asset_amount adalah kuotasi terkunci penuh, termasuk spread dan pembulatan ke atas, tidak pernah ambang toleransi atau sisa saldo. paid_asset_amount_received adalah total penerimaan valid metode pemenang saat penyelesaian, termasuk dana yang menunggu konfirmasi serta kekurangan atau kelebihan yang diterima. Contoh: kuotasi 100 USDC, 99 diterima dan disetujui dengan toleransi menghasilkan 100 dan 99, bukan 99 dan 99. Keduanya dibekukan bersama snapshot penyelesaian; gunakan payment_info.methods[].amounts untuk penerimaan pada setiap peristiwa atau API pembayaran untuk catatan terkini. Nilainya null tanpa snapshot yang memenuhi syarat dan untuk snapshot sebelum 5.0.1; body peristiwa lama dalam antrean tetap sama. Jangan pernah mengonversi string desimal presisi ke floating point untuk akuntansi.
settlement_exchange_rate adalah observasi pasar dalam cache sebelum spread yang dicatat bersama penyelesaian, bukan kuotasi faktur terkunci atau perdagangan bursa yang dieksekusi. Strukturnya sesuai dengan market_rate_at_event; 1.17 asset_per_invoice_currency dengan EUR/USDC berarti 1 EUR = 1.17 USDC. Stempel waktu sumber serta penanda stale/fixed/proxy menjelaskan kualitasnya. Pasangan yang tidak tersedia membuat kurs null, tetapi metode yang terbukti tetap memiliki kolom paid_*. Ini tidak pernah mengubah jumlah terutang atau menunggu panggilan langsung ke penyedia. Pembayaran berikutnya dengan metode yang sama, percobaan ulang, dan pengiriman ulang tidak bisa mengganti snapshot tersimpan, termasuk kurs null yang disimpan. Penyelesaian ulang yang sah atau perubahan metode penyelesaian mencatat snapshot baru; observed_at mengidentifikasi pencatatan tersebut, sementara settled_at bisa mempertahankan waktu penyelesaian pertama. Body peristiwa lama tetap sama.
Paling banyak delapan metode teramati dan lima observasi pembayaran terbaru per metode disertakan, dengan jumlah dan penanda pemotongan. Batas ukuran payload bisa mengurangi array tersebut lebih lanjut. Satu observasi pembayaran adalah satu transfer/log/output UTXO, belum tentu hash transaksi unik. Gunakan GET /v1/projects/YOUR_PROJECT_ID/invoices/{invoice_id}/payments dengan payment_method_id, limit, dan offset untuk riwayat terkini lengkap. Detail faktur mempertahankan setiap metode yang diberi kuotasi dan quote_details-nya. Tautan API memerlukan host serta kredensial yang kamu konfigurasi; jangan pernah meneruskan token bearer ke sembarang URL dari callback.
Lightning menggunakan payment_hash, bukan transaction_id; alamat penerimaan, penjelajah, dan konfirmasi teramati bernilai null. Jumlah BTC presisinya menggunakan 11 desimal (millisatoshi), dan toleransi efektif nol. Tidak menyertakan preimage pembayaran BOLT11, kunci dompet, rahasia penandatanganan, atau kredensial penyedia. Kolom pelanggan/metadata hanya boleh ada dalam respons merchant dan callback bertanda tangan, jangan pernah checkout publik; jangan memasukkan kredensial dalam metadata.
Terima dengan aman
- Verifikasi body mentah secara persis dengan rahasia yang sesuai sebelum parsing. Toko → IPN menyediakan rahasia IPN, termasuk pengiriman ipn_url kustom. Setiap endpoint Toko → Webhook memiliki rahasianya sendiri. Keduanya bukan token API-mu; merotasi satu tidak merotasi yang lain.
- Periksa stempel waktu bertanda tangan (bawaan SDK: lima menit ke kedua arah) dan cocokkan ID proyek/toko bertanda tangan dengan konfigurasi penerima jika ada. Antrekan secara persisten sebelum mengembalikan HTTP 2xx. Untuk pemrosesan per peristiwa, event_id v2 ditandatangani; ID header saja bukan perlindungan replay karena header tersebut tidak ditandatangani. Untuk kotak masuk status pesanan, deduplikasi invoice_id dan sequence serta bandingkan kolom status faktur asli, bukan seluruh body v2: jenis/ID peristiwa berbeda bisa berbagi satu revisi.
- Di worker, ambil faktur terkini dari origin API yang kamu konfigurasi, bukan sembarang tautan callback. Cocokkan pesanan tersimpan, proyek/toko, jumlah, dan mata uang, wajibkan status terkini settled, serta terapkan kebijakan penerimaan manual dan pengecualianmu. Kunci pesanan dan penuhi satu kali dalam transaksi database, secara independen dari deduplikasi peristiwa.
- Jangan pernah menerapkan sequence lama di atas yang lebih baru. Peristiwa berbeda bisa berbagi satu revisi; jangan gabungkan deduplikasi tingkat revisi dengan filter khusus invoice.settled. Pembukaan ulang/rekonsiliasi bisa mengubah status; sequence, bukan peringkat status tetap, mengurutkan pembaruan. Catat pembalikan untuk ditinjau, jangan memenuhi pesanan lagi.
Contoh penerima: PHP · Python · Node.js / TypeScript.
Verifikasi tanda tangan & aturan pengiriman
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);
}| Aturan pengiriman | Detail |
|---|---|
| Header | Wholly-Signature, Wholly-Event-Id, dan Wholly-Delivery-Id; Content-Type adalah application/json. |
| Tanda tangan | HMAC-SHA256 atas <unix timestamp>.<exact raw body>; format header t=<timestamp>,v1=<64 lowercase hex>. |
| Berhasil | Respons HTTP 2xx apa pun. Pengalihan tidak diikuti; respons non-2xx dianggap gagal. |
| Batas waktu | Batas waktu koneksi 5 detik dan batas waktu total permintaan 10 detik. |
| Jadwal percobaan ulang | Hingga 8 percobaan untuk kegagalan yang bisa dicoba ulang: segera, lalu jeda 10s, 1m, 5m, 15m, 1h, 6h, dan 24h setelah percobaan sebelumnya selesai. IPN mencoba ulang otomatis; percobaan ulang otomatis webhook bisa dinonaktifkan per endpoint. |
| Keamanan tujuan | Hanya HTTPS publik. DNS divalidasi ulang dan dipin untuk pengiriman; tujuan lokal/privat/yang dicadangkan ditolak. |
| Retensi peristiwa | Payload peristiwa notifikasi dan pengiriman dijadwalkan disimpan selama 90 hari; detail tersimpan dibersihkan dalam batch terbatas. |
| Deduplikasi | Simpan invoice_id dan sequence bertanda tangan secara persisten dalam cakupan proyek yang dikonfigurasi. Wholly-Event-Id mengidentifikasi peristiwa; Wholly-Delivery-Id mengidentifikasi catatan pengiriman (percobaan ulang memakainya kembali; pengiriman ulang manual membuat yang baru). Kedua header ID tidak ditandatangani. |
| Penamaan peristiwa | Versi 2 menandatangani event_id dan event_type dalam body. Peristiwa lama dalam antrean tidak memiliki keduanya. Jenis peristiwa berbeda bisa berbagi sequence faktur; rekonsiliasikan status faktur berdasarkan revisi, atau deduplikasi peristiwa individual berdasarkan event_id bertanda tangan. |
| Rotasi rahasia | Rotasi tidak memiliki masa tumpang tindih atau header versi dan langsung mengubah tanda tangan untuk pengiriman dalam antrean, percobaan ulang, dan pengiriman manual. |
| Pengiriman yang dijeda | Kredit pemrosesan yang tidak mencukupi menjeda IPN/webhook, termasuk percobaan ulang. Pembayaran masuk tetap berjalan; notifikasi dalam antrean dilanjutkan setelah pendanaan selama masih dalam masa retensi payload. |
Asisten AI · MCP
Hubungkan asisten ke instalasi merchant-mu.
Merchant 5.0.0 menyertakan server MCP opsional di domain API yang kamu konfigurasi. Server ini berjalan dalam instalasimu, bukan melalui relay bersama Wholly Crypto.
- Buka Pengaturan → Akses API. Buat kredensial khusus, tetapkan hanya proyek yang diperlukan asisten, dan mulai dengan akses hanya baca. Pada akun yang dihosting operator, operator mengaktifkan layanan MCP instalasi terlebih dahulu; kamu hanya mengelola kredensial serta izinmu sendiri.
- Di Koneksi AI · MCP, aktifkan MCP, pilih kredensial, dan simpan akses MCP-nya. Kredensial yang ada tidak memiliki akses MCP sampai diaktifkan secara eksplisit.
- Salin URL server MCP ke pengaturan server HTTP jarak jauh klienmu. Dengan OAuth, login ke konsol merchant, tinjau nama klien dan alamat kembali, pilih kredensial, dan setujui. Perlindungan Basic Auth dan TOTP yang ada tetap berlaku.
- Pembuatan faktur juga memerlukan kredensial baca/tulis, Baca + buat faktur dalam kebijakan MCP-nya, cakupan OAuth mcp:invoice:create, dan persetujuan eksplisit. Koneksi OAuth tidak pernah memperoleh proyek yang ditambahkan ke kredensial setelah persetujuan.
{
"mcpServers": {
"whollycrypto": {
"url": "https://api.example.com/mcp"
}
}
}| Alat | Akses | Tujuan |
|---|---|---|
| list_projects | Baca | Proyek aktif yang ditetapkan ke koneksi; paginasi limit/offset. |
| list_stores | Baca | Toko, ID, dan status aktif dalam project_id; paginasi limit/offset. |
| list_payment_methods | Baca | Metode blockchain, token, dan Lightning yang dikonfigurasi untuk project_id + store_id. |
| get_wallet_balances | Baca | Alamat penerimaan dan saldo dalam cache, dengan kolom kebaruan/ketersediaan; tidak pernah rahasia dompet. |
| list_invoices | Baca | Faktur proyek, difilter berdasarkan toko, status, atau pencarian; paginasi limit/offset. |
| get_invoice | Baca | Detail faktur lengkap dan tautan checkout menggunakan project_id + invoice_id. |
| get_delivery_history | Baca | Status IPN/webhook toko, percobaan, dan hasil HTTP. Filter invoice_id/kind opsional; tanpa rahasia atau body callback. |
| convert_amount | Baca | Konversi referensi dalam cache menggunakan from, to, dan amount berupa string desimal; bukan kuotasi faktur. |
| create_invoice | Penulisan eksplisit | project_id, store_id, idempotency_key, dan invoice (body pembuatan faktur yang ada). invoice.payment_methods memfilter metode toko yang aktif; 5.4.0+ mengabaikan pilihan nonaktif/tidak diterima dan kembali ke pengaturan bawaan toko jika tidak ada yang cocok. Pilihan blockchain saja memilih semua aset aktif yang diterima. asset_tickers dengan cakupan blockchain didukung mulai 5.3.0. Mengembalikan respons faktur normal. |
Protokol, OAuth & keamanan
Gunakan Streamable HTTP melalui HTTPS. Negosiasikan versi protokol yang diumumkan dan sertakan MCP-Protocol-Version pada POST selanjutnya. Kirim Content-Type: application/json dan Accept: application/json, text/event-stream. Respons berupa JSON terbatas; koneksi ulang tidak memerlukan ID sesi MCP.
OAuth menggunakan token akses berumur pendek (15 menit), kode S256 PKCE sekali pakai (5 menit), dan token penyegaran berotasi (masa koneksi 30 hari). Memakai ulang token penyegaran yang sudah dipakai mencabut koneksi tersebut. Hubungkan kembali setelah kedaluwarsa, rotasi kredensial, perubahan kebijakan, atau perubahan domain API kanonis.
Penemuan OAuth hanya publik saat MCP diaktifkan. Parameter resource harus sama dengan URL kanonis yang dikembalikan penemuan, termasuk /mcp. Pendaftaran dinamis didukung; dokumen metadata ID klien jarak jauh dan rahasia klien tidak didukung.
Untuk klien yang mendukung header Authorization kustom, token API merchant yang mengaktifkan MCP bisa digunakan sebagai Bearer. Token ini mempertahankan izin REST terpisahnya; utamakan OAuth untuk koneksi yang dibatasi ke MCP. Jangan pernah menempelkan kredensial dalam percakapan, URL, argumen alat, atau kontrol versi.
MCP berbagi kuota REST per menit dan pembatasan IP sumber persis milik kredensial, ditambah pembatasan IP host API. OAuth tidak melewati daftar izin. Untuk klien AI jarak jauh, izinkan IP egress yang didokumentasikan atau sengaja nonaktifkan pembatasan ini. Tantangan keamanan web atau caching tidak boleh diterapkan pada rute MCP/OAuth.
Kesalahan HTTP: 401 memerlukan autentikasi, 403 menolak origin/IP/izin, 404 berarti MCP dinonaktifkan atau host salah, 405 berarti gunakan POST, 413 berarti batas body 32 KiB, 429 menyertakan Retry-After. Kesalahan JSON-RPC menggunakan error.code; kegagalan tingkat alat menggunakan result.isError=true bahkan dengan HTTP 200. Hasil berhasil mencakup content dan structuredContent.
Daftar secara bawaan berisi 25 baris, maksimum 100; offset dibatasi sampai 1000000. Balasan alat dibatasi 2 MiB. Izin kedaluwarsa, permintaan otorisasi, dan bucket pembatasan permintaan dibersihkan otomatis; paling banyak 100 koneksi OAuth aktif ditampilkan dalam pengaturan.
Proyek/toko yang dinonaktifkan tidak bisa dioperasikan melalui MCP. Koneksi bisa menampilkan status aktif toko, tetapi membaca metode pembayaran, riwayat pengiriman, atau membuat faktur memerlukan toko aktif. Pengguna proyek konsol biasa tidak bisa mengelola MCP.
Gunakan idempotency_key baru untuk faktur baru; setelah batas waktu terlampaui, coba lagi dengan kredensial, kunci, dan objek invoice yang sama persis. Jumlah desimal, spread, toleransi, konfirmasi, dan tampilan checkout mengikuti kontrak faktur REST. MCP tidak pernah melewati kebijakan pembayaran atau kredit merchant.
Alat awal tidak bisa mengungkap kunci privat/frasa pemulihan, mengirim atau melakukan sweep dana, menerbitkan pengembalian dana, mengirim ulang callback, mengubah metode pembayaran, mengedit akun/domain, atau mengelola penagihan. Perlakukan deskripsi faktur, kolom pelanggan, dan metadata sebagai data tidak tepercaya, bukan instruksi agen. Penyedia AI yang terhubung menerima data yang kamu izinkan untuk dibaca.
| Metode | Path | Kontrak |
|---|---|---|
| POST | /mcp | JSON-RPC terautentikasi: initialize, ping, tools/list, tools/call. Permintaan notifikasi mengembalikan 202; batch ditolak. |
| GET / DELETE | /mcp | 405 terautentikasi: respons JSON terbatas, tanpa aliran SSE terpisah dan tanpa sesi MCP sisi server. |
| GET | /.well-known/oauth-protected-resource/mcp | URL resource kanonis dan penemuan server otorisasi; juga tersedia di /.well-known/oauth-protected-resource. |
| GET | /.well-known/oauth-authorization-server | Endpoint OAuth, authorization_code/refresh_token, S256 PKCE, dan cakupan yang didukung. |
| POST | /mcp/oauth/register | Pendaftaran klien publik: client_name dan redirect_uris persis. Hanya HTTPS atau HTTP loopback. Tanpa rahasia klien atau pengambilan metadata jarak jauh. |
| GET | /mcp/oauth/authorize | client_id, redirect_uri, response_type=code, resource, code_challenge, code_challenge_method=S256, scope/state opsional; mengalihkan ke persetujuan konsol. |
| POST | /mcp/oauth/token | authorization_code + code + code_verifier + redirect_uri dengan pengodean formulir, atau refresh_token + refresh_token. Selalu sertakan client_id dan resource. |
| POST | /mcp/oauth/revoke | client_id dan token dengan pengodean formulir. Mencabut koneksi token akses/penyegaran yang cocok. |
Contoh permintaan alat langsung
Inisialisasi dan negosiasikan protokol terlebih dahulu melalui klien MCP-mu. Ini menunjukkan permintaan berikutnya.
: "${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
Siapkan merchant yang dihosting dengan kunci sisi server terpisah yang dibatasi cakupannya.
Hosting beberapa bisnis dan otomatiskan penyiapannya melalui api.example.com/v1/operator. Tersedia mulai 7.4.0 hanya dalam mode Operator. API Merchant biasa tetap sama.
- Buka Operator → Pengaturan → API Operator dan aktifkan (nonaktif secara bawaan). Buat kredensial terpisah dengan hanya izin dan merchant yang dihosting yang diperlukan.
- Simpan kunci wc_operator_ di servermu. Gunakan nama host API, bukan nama host panel Operator atau kunci merchant.
- Simpan Idempotency-Key dan body permintaan persis secara persisten sebelum setiap POST Operator. Baca kembali akun setelah hasil yang belum pasti; jangan pernah mengganti kunci hanya untuk mencoba ulang.
- Buat merchant dengan onboarding: direct dan kata sandi, atau onboarding: invitation tanpa kata sandi. Lalu buat proyek/toko dan terbitkan kunci merchant dengan cakupan proyek untuk integrasi checkout-nya.
| Cakupan | Akses |
|---|---|
| merchants.read / merchants.write | Daftar/baca serta buat/perbarui merchant yang dihosting. |
| users.read / users.write / users.security | Baca/buat/perbarui pengguna; ubah kata sandi atau cabut sesi secara terpisah. Tidak pernah membuat administrator operator. |
| invitations.read / invitations.write | Daftar/baca, buat, ganti, dan cabut tautan undangan/reset sekali pakai. Pengguna baru juga memerlukan users.write; reset juga memerlukan users.security. |
| credits.read / credits.write / fees.write | Baca saldo/buku besar; berikan atau koreksi kredit lokal; tetapkan biaya untuk ke depan. Kredit awal bukan nol memerlukan credits.write. |
| topups.read / topups.write | Baca atau buat permintaan checkout kredit merchant yang dihosting. Tidak ada tindakan API yang bisa menandainya lunas. |
| projects.read / projects.write / reports.read | Siapkan proyek, toko, tampilan, dan pengaturan pembayaran merchant; baca faktur, saldo dompet, dan laporan keuangan. |
| merchant_credentials.read / merchant_credentials.write | Kelola kunci merchant biasa dengan cakupan terbatas. Kewenangannya besar: kunci tersebut bertindak independen setelah diterbitkan. |
| events.read / webhooks.write / audit.read / health.read | Baca riwayat siklus hidup; konfigurasikan callback siklus hidup bertanda tangan; baca audit/kemampuan/kesehatan node. |
Pendaftaran, kredit, izin, dan percobaan ulang yang aman
| Topik | Aturan |
|---|---|
| Kredensial | Kedaluwarsa opsional dan daftar izin IPv4/IPv6 persis; bawaan 60 permintaan/menit, dapat dikonfigurasi 1–600. Setiap permintaan memeriksa administrator penerbit dan cakupan terkini. HTTP 429 menyertakan Retry-After. |
| Isolasi | Kunci hanya mengakses merchant yang dihosting yang ditetapkan padanya. Membuat merchant dan melihat laporan seluruh instalasi memerlukan akses semua merchant. Bisnis operator sendiri dikecualikan. |
| Login pertama | Akun langsung mengakui bahwa host bisa mengakses kunci dompet mereka. require_password_change menambahkan perubahan kata sandi saat login pertama. Penerimaan undangan memerlukan pengakuan kustodi secara eksplisit, lalu login normal. Basic Auth dan TOTP yang ada tetap berlaku. |
| Undangan | Tautan pengguna baru berlaku 48 jam; tautan reset kata sandi berlaku satu jam. Token sekali pakai. Penerbitan ulang mencabut tautan lama. Penerimaan SMTP tidak menjamin email sampai ke kotak masuk; periksa email_delivery. |
| Percobaan ulang yang aman | Setiap POST Operator memerlukan kunci 16–128 karakter (huruf, angka, -, _, atau .). Kunci yang sama dan URL/body persis mengembalikan hasil tersimpan. Byte berbeda mengembalikan 409. Rahasia/tautan dihilangkan pada replay; rotasi atau terbitkan ulang melalui operasi eksplisit baru bila diperlukan. |
| Hasil yang belum pasti | operator_request_in_progress berarti operasi sedang berjalan atau terputus sebelum tanda terimanya dicatat. Periksa resource dan audit; jangan sembarangan mengirim kunci baru. Tanda terima selesai dipadatkan setelah 30 hari; kunci lama tetap tidak bisa dijalankan lagi. |
| Kredit dan biaya | String desimal, paling banyak enam desimal. starting_credit adalah pemberian lokal satu kali. Penyesuaian memerlukan jumlah bertanda positif/negatif, catatan, dan request_id, ditambah kunci percobaan ulang HTTP. fee_bps=100 berarti 1%; perubahan memengaruhi faktur mendatang. Pemberian kredit tidak mengisi ulang saldo prabayar instalasi sendiri. |
| Penjedaan | enabled=false menonaktifkan akun yang dihosting dan mencabut sesi konsol. payments_paused=true menghentikan faktur baru. Pemantauan pembayaran yang ada berlanjut. Pembuatan proyek/toko dan otomatisasi mempertahankan kebijakan kredit instalasi. |
| Tidak tersedia | Tanpa rahasia dompet, penandatanganan, pengiriman, pengembalian dana, penghapusan permanen, reset TOTP, perubahan domain, atau konfigurasi tingkat server. Permintaan faktur biasa tetap menggunakan kunci merchant dan API Merchant. |
Webhook siklus hidup Operator
| Peristiwa | Data |
|---|---|
| merchant.created / merchant.updated | merchant_id, enabled, payments_paused, fee_bps. |
| user.created / user.updated | merchant_id, user_id, enabled. Peristiwa pembaruan mencakup perubahan email, status aktif, dan peran admin. |
| invitation.accepted / password_reset.completed | merchant_id, user_id, invitation_id. |
| topup.settled / credit.balance_changed | merchant_id, ledger_id, kind, amount, dan balance. Baca mata uang kredit merchant atau detail buku besar saat rekonsiliasi. |
Peristiwa siklus hidup Operator terpisah dari IPN faktur/webhook toko. Langganan dimiliki kredensial Operator yang membuatnya, dengan hingga 10 endpoint per kunci. Hanya peristiwa cocok di masa mendatang yang masuk antrean; gunakan GET /events untuk riwayat tersimpan.
Body berisi event_id, event_type, merchant_id, occurred_at, dan data. Verifikasi Wholly-Signature atas body mentah persis menggunakan signing_secret endpoint yang ditampilkan satu kali: HMAC-SHA256(secret, timestamp + '.' + raw_body), header t=...,v1=.... Terapkan toleransi stempel waktu singkat.
Gunakan verifier tanda tangan generik SDK, bukan parser notifikasi fakturnya. Lalu validasi merchant_id dan event_type, simpan/deduplikasi event_id secara transaksional, dan kembalikan 2xx hanya setelah penerimaan persisten. Wholly-Event-Id harus cocok dengan body bertanda tangan. Jangan perlakukan header tanpa tanda tangan sebagai data bisnis.
Pengiriman setidaknya satu kali, bisa datang tidak berurutan, dan dicoba hingga 8 kali. Baca resource terkini untuk rekonsiliasi; occurred_at bukan urutan monoton. Cakupan dan pengaturan aktif/kedaluwarsa diperiksa ulang sebelum pengiriman. Langganan yang dinonaktifkan menjeda pekerjaan yang sudah masuk antrean, tetapi tidak mengantrekan peristiwa baru selama nonaktif.
Peristiwa dan riwayat pengiriman disimpan 30 hari. Kebijakan otomatisasi instalasi bisa menjeda pengiriman. GET /webhooks/{id}/deliveries menampilkan hasil dan payload yang tidak dapat diubah; API publik tidak memaksa pengiriman catatan yang kedaluwarsa.
{
"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 Marketplace
Satu checkout dengan bagian vendor yang dilindungi dan pembayaran terkontrol.
Satu faktur pelanggan, bagian vendor presisi, dan pembayaran terkontrol dalam aset yang sama. Aktifkan per proyek. Versi 8.0.0 mendukung mainnet Bitcoin serta koin native EVM / token ERC-20 standar yang didukung dan dikonfigurasi, bukan semua jaringan penerimaan.
- Aktifkan Marketplace dalam proyek, pilih toko yang berpartisipasi, dan biarkan pembayaran dijeda selama konfigurasi.
- Daftarkan vendor dan verifikasi alamat pembayaran mereka secara independen. Tujuan yang dibuat berstatus tertunda; persetujuan memerlukan destinations.approve.
- Buat kredensial Marketplace terpisah di Pengaturan → Akses API. Kredensial Merchant biasa, Operator, dan MCP tidak bisa membelanjakan dana Marketplace.
- Buat faktur dengan 1–100 alokasi positif berupa string desimal yang totalnya sama persis dengan jumlah faktur. Setiap vendor memerlukan tujuan yang disetujui pada satu jaringan toko yang sama dan didukung.
- Tunggu ketersediaan alokasi terverifikasi. Siapkan pembayaran, baca penerima dan batas biaya yang tidak dapat diubah, lalu setujui revisi dan plan_hash persisnya. Polling pembayaran atau verifikasi peristiwa bertanda tangan.
| Topik | Aturan |
|---|---|
| Kustodi | Dana pelanggan masuk ke dompet yang dikendalikan proyek terlebih dahulu. Pemilik marketplace/server mengendalikan kunci tersebut sampai vendor dibayar. Ini bukan pembayaran langsung pelanggan ke vendor, escrow, atau sistem login vendor. |
| Tiga vendor | Faktur 300 USD dengan tiga bagian 100 USD dan komisi 4% mengalokasikan kripto yang dikuotasikan senilai 96 USD kepada setiap vendor, menyisakan komisi kotor senilai 12 USD. Unit atomik kripto, bukan nilai fiat masa depan, dijamin oleh rencana. |
| Biaya | Biaya pemrosesan yang ada berlaku sekali untuk jumlah/mata uang faktur asli yang diselesaikan. Pada tarif 1% yang dikonfigurasi, biayanya 3 USD kredit prabayar, menyisakan komisi senilai 9 USD sebelum biaya blockchain. Pembayaran vendor tidak menimbulkan biaya penjualan pelanggan tambahan. |
| Alokasi | Alokasi sisa terbesar mempertahankan setiap unit atomik. Komisi dibulatkan ke bawah; bagian bersih vendor adalah sisanya. Pengesampingan alokasi, faktur, vendor, dan pengaturan bawaan toko/proyek disimpan dalam snapshot. Tidak ada kurs baru yang diterapkan saat pembayaran. |
| Dana yang dilindungi | Pengiriman biasa, sweep, deposit bursa, dan isi ulang kredit otomatis mengecualikan alamat penerimaan Marketplace. Biaya jaringan dan gas token memerlukan koin native bebas yang terpisah. Nilai dompet dalam cache bersifat referensi; kecukupan dana terkini diperiksa secara independen sebelum penandatanganan. |
| Finalitas | Batas minimum blockchain yang positif dan dua penyedia kompatibel independen diperlukan untuk bukti pembayaran Marketplace, bahkan jika checkout menerima nol konfirmasi atau satu pemindai. Masa tunggu penyedia menunda verifikasi pembayaran/pembayaran vendor, bukan pembuatan faktur yang memenuhi persyaratan lainnya. |
| Pengecualian | Kekurangan pembayaran yang diterima oleh toleransi checkout biasa ditahan, bukan dialokasikan berlebihan. Pelepasan dengan hak khusus bisa menyetujui pembagian presisi yang lebih kecil dan sepenuhnya didukung dana. Kelebihan pembayaran saja tidak pernah memblokir pembagian vendor yang dikuotasikan pada BTC atau metode native EVM/ERC-20 yang didukung. Kelebihan tetap ditahan terpisah. Bitcoin mengembalikan kembalian yang dilindungi ke alamat faktur; dana proyek terpisah menanggung biaya dan isi ulang untuk batas minimum dust jika ada. Metode campuran, pembayaran terlambat/ambigu/terkena reorg, dan dana pendukung yang kurang perlu ditinjau. |
| Pengembalian dana | Siapkan pengembalian penuh dalam aset yang sama dari satu metode penerimaan terkonfirmasi yang tidak ambigu, lalu setujui secara terpisah sebagai pembayaran. Alokasi yang belum dibayar dan komisi dibalik. Setelah semua vendor dibayar, danai alamat dompet utama secara terpisah; tidak ada penarikan kembali. Batch vendor parsial dan pengembalian dana lintas aset memerlukan rekonsiliasi terlebih dahulu. Pengembalian sebagian jumlah dan penarikan komisi tidak tersedia di 8.0.0. |
| Percobaan ulang | Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti. |
| Revisi | Catatan yang bisa diubah memerlukan revisi terkininya. Persetujuan/pelanjutan juga memerlukan expected_plan_hash dan confirm:true. Penyiapan mencadangkan dana selama 15 menit; persetujuan mengizinkan satu jam. Pekerjaan belum ditandatangani yang kedaluwarsa dilepaskan dengan aman. Transfer yang ditandatangani/belum pasti mempertahankan identitas dan pencadangan dana. |
| Pembayaran otomatis | Nonaktif secara bawaan. Kebijakan per aset mengotorisasi tujuan yang disetujui, minimum positif, batas pokok per pembayaran/periode berjalan 24 jam, batas biaya native/gas, interval, dan konfirmasi. Mengubah/mencabut wewenang menghentikan pekerjaan yang belum dikirim; observasi berlanjut. Batas mencakup rencana yang dicadangkan dan belum pasti. Kebijakan yang dijeda penagihan dijadwalkan ulang secara adil. Faktur tidak valid ditahan untuk ditinjau tanpa memblokir kelompok faktur lain yang memenuhi syarat. |
| Jeda dan pemulihan | Kredit rendah dan gerbang keamanan transfer tetap menjeda pembelanjaan. Pemantauan dan rekonsiliasi buku besar berlanjut. Pelanjutan meninjau rencana tersimpan yang sama. Revert EVM kanonis yang dibuktikan dua penyedia independen bisa diganti setelah persetujuan eksplisit, dalam sisa anggaran biaya; hash dan biaya asli tetap dicatat. Hasil yang tidak diketahui atau ketidakcocokan pengiriman token tetap ditahan. Cadangkan seluruh database dan kunci; rekonsiliasikan hash yang sudah diajukan setelah pemulihan sebelum mengizinkan pembayaran. |
| Pengenal dan paginasi | Gunakan UUID proyek dari Pengaturan Proyek dan UUID toko dari Toko → Dasar → ID API. ID vendor/pembayaran/aset dikembalikan oleh API ini. invoice_id adalah UUID faktur publik. Resource berhalaman mengembalikan data dan pagination {page,per_page,total,pages}; bawaan 1/25, maksimum 100 baris. Nilai uang presisi berupa string. |
| Cakupan kredensial | Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan. |
Izin Marketplace
marketplace.read · vendors.write · destinations.write · destinations.approve · invoices.write · policies.write · commissions.override · payouts.write · payouts.approve · webhooks.write · reconciliation.write
Status alokasi
pending · held · available · reserved · paid · refunding · refunded · shortfall
Status pembayaran
awaiting_approval · queued · funding_gas · sending · confirming · partially_paid · paid · needs_attention · cancelled · expired
Peristiwa Marketplace
Rahasia penandatanganan Marketplace terpisah, menggunakan header tanda tangan Wholly dan algoritma verifikasi HMAC body mentah yang sama dengan callback faktur. Verifikasi stempel waktu/tanda tangan, deduplikasi event_id, dan segera kembalikan 2xx. Pengiriman setidaknya satu kali, hingga delapan percobaan; riwayat bisa mengirim ulang peristiwa yang sama. Perubahan endpoint membatalkan pengiriman lama yang belum dikirim, bukan mengalihkan data pelanggan. Penyelesaian faktur bukan selesainya pembayaran vendor. Jangan pernah mengirim uang hanya karena callback eksternal menyuruhnya.
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"
}
]
}
}Kesalahan & batasan
Tangani validasi, kuota, dan percobaan ulang secara terprediksi.
Periksa status HTTP dan Content-Type sebelum parsing respons. Untuk 429, tunggu setidaknya selama Retry-After sebelum mencoba lagi.
| Batas | Detail |
|---|---|
| Laju permintaan | Kuota per kredensial: bawaan 120 permintaan per menit UTC, dapat dikonfigurasi dari 1 sampai 6000 di Pengaturan → API. Semua pembacaan dan penulisan v1 terautentikasi, termasuk percobaan ulang idempoten serta kegagalan otorisasi/validasi setelah autentikasi, berbagi jatah lintas domain, proyek, dan proses. Kredensial tidak valid, rute konsol, dan checkout publik tidak menggunakannya. |
| Header pembatasan permintaan | Respons v1 terautentikasi mencakup X-RateLimit-Limit, X-RateLimit-Remaining, dan X-RateLimit-Reset (detik Unix pada batas menit UTC berikutnya). Permintaan berlebih mengembalikan JSON 429 rate_limit_exceeded dan Retry-After dalam detik bulat. Tunggu setidaknya selama itu dan tambahkan variasi acak pada jeda percobaan ulang. Jendela tetap memungkinkan lonjakan pada batas menit; ini bukan jaminan permintaan per detik. |
| Body merchant | Maksimum 32 KiB pada router aplikasi. Edge bisa menolak permintaan terlalu besar sebelum envelope kesalahan JSON dihasilkan. |
| Daftar faktur | limit bawaan 50 dan menerima 1–100; offset menerima 0–1,000,000. Pencarian paling banyak 100 karakter. Hasil diurutkan dari yang terbaru dan menyertakan metadata total/has_more. |
| Metode toko | Paling banyak 64 pilihan aset per toko, cukup untuk seluruh 30 blockchain native ditambah katalog token terverifikasi yang dibatasi. Kebijakan proyek, kemampuan pemindai, dan dompet blockchain siap pakai yang sudah dicadangkan tetap menjadi syarat pembuatan faktur. |
| Penemuan token | Batas kandidat bawaan 50 dan menerima 1–100. Hasil penemuan belum menjadi aset pembayaran sampai verifikasi on-chain berhasil. |
| Token proyek terdaftar | Paling banyak 20 aset token persisten per proyek. Aset yang sudah terdaftar bisa digunakan kembali tanpa memakai slot lain. |
| Idempotensi | Wajib untuk pembuatan faktur. 1–128 karakter ASCII terlihat tanpa spasi; kunci unik per toko, dan replay harus menggunakan kredensial asli serta body mentah persis. |
| Metadata | Hanya objek JSON, maksimum 4,096 byte terenkode dan lima tingkat penyarangan. |
| Callback | URL HTTPS publik hingga 2,048 byte. Body permintaan notifikasi dibatasi 256 KiB; payload peristiwa faktur tersimpan dibatasi 64 KiB dengan riwayat pembayaran terbatas. |
| Aset checkout | Respons QR SVG bersifat private dan no-store karena kekurangan pembayaran mengubah sisa presisi. Logo PNG dengan revisi disimpan dalam cache publik selama satu tahun dan tidak dapat diubah. |
| Edge API | Permintaan upstream API yang dikelola memiliki batas waktu baca 30 detik. Rancang pemanggil dengan batas waktu eksplisit yang lebih pendek dari anggaran waktu pekerjaannya. |
| Kegagalan non-JSON | Ekstraksi UUID/kueri yang salah format, metode yang salah, dan batas panjang 32 KiB bisa mengembalikan respons teks/kosong framework. Path /v1 yang tidak dikenal saat ini mengembalikan HTML konsol 404; validasi status dan Content-Type sebelum parsing. |
Referensi kesalahan
| HTTP | Kode kesalahan | Arti |
|---|---|---|
| 400 | invalid_reconciliation_action | Filter status pengecualian, alasan, pencarian, atau halaman riwayat tidak valid. |
| 500 | reconciliation_unavailable | Antrean pengecualian atau bukti tidak bisa dimuat. Coba ulang pembacaan dengan jeda yang bertambah. |
| 402 | billing_required | Akun kredit berpasangan yang terverifikasi dan otorisasi aktif diperlukan untuk setiap faktur baru. Kredit prabayar yang tidak cukup tidak memblokir pembuatan atau pembayaran masuk: IPN, webhook, dan Sweep yang dijeda, sementara biaya terus terakumulasi. Pembuatan tetap diblokir untuk akun ditangguhkan, verifikasi penagihan kedaluwarsa/tidak valid, layanan kredit tidak terjangkau, atau dasar fiat faktur yang tidak diotorisasi. Biaya menggunakan jumlah fiat faktur asli, bukan kripto diterima, spread, kelebihan pembayaran, atau biaya jaringan. Jumlah tersebut dan konversi independen didaftarkan sebelum pembuatan checkout. Pemantauan dan pengambilan faktur yang ada berlanjut selama gangguan. Setelah pendanaan, notifikasi dalam antrean dilanjutkan dalam masa retensi payload normal, dan aturan sweep aktif dilanjutkan. Periksa Pengaturan → Biaya dan coba ulang pembuatan gagal dengan Idempotency-Key yang sama. |
| 400 | invalid_json | JSON salah format, kolom tidak dikenal, atau body yang tidak sesuai dengan permintaan terdokumentasi. |
| 400 | idempotency_key_required | Pembuatan faktur tidak menyertakan Idempotency-Key. |
| 400 | invalid_idempotency_key | Kunci kosong, lebih dari 128 byte, non-ASCII, mengandung spasi, atau mengandung byte kontrol. |
| 400 | invalid_payment_request | Kolom tervalidasi atau metode aktif yang dipilih gagal. Baca error.message dan error.details.payment_methods (PaymentMethodIssue[]) untuk penyebab tepatnya. SDK 2.4.0+ menambahkan ringkasan pengecualian aman yang bisa ditindaklanjuti serta helper masalah; SDK PHP lama menyediakan getApiMessage(). |
| 400 | invalid_invoice_status | Status daftar berada di luar enam status faktur yang didokumentasikan. |
| 400 | invalid_callback_url | Tujuan IPN efektif gagal dalam validasi HTTPS, alamat publik, DNS, atau SSRF. |
| 400 | invalid_wallet_request | Input penyiapan dompet/alamat tidak valid. |
| 400 | invalid_token_asset | Blockchain token, kueri kandidat, identitas CoinGecko, metadata katalog, atau input kontrak/mint tidak valid. |
| 401 | authentication_required | Token bearer tidak ada, salah format, dinonaktifkan, dirotasi, atau tidak dikenal. |
| 403 | source_ip_denied | Pembatasan IP kredensial tidak mencakup alamat sumber publik permintaan secara persis. |
| 403 | source_ip_not_allowed | Pembatasan IP sumber nama host mengecualikan klien ini. Administrator bisa mengelola daftar izin host aktif di Pengaturan → Sistem; ini berlaku selain pembatasan IP kredensial. |
| 503 | source_access_unavailable | Verifikasi akses nama host sementara tidak tersedia. Coba lagi nanti; pembatasan tetap menolak akses saat pemeriksaan gagal. |
| 403 / 409 / 500 | merchant_api_access_denied | Otorisasi gagal: izin/cakupan proyek bisa menghasilkan 403, proyek/toko nonaktif bisa menghasilkan 409, dan kegagalan backend otorisasi bisa menghasilkan 500. Dompet penerimaan Operator dikhususkan untuk panel Operator, bukan kredensial API merchant atau MCP, bahkan dengan izin proyek eksplisit lama. |
| 403 | project_access_denied | Pemeriksaan ulang transaksional saat pembuatan menemukan bahwa kredensial tidak lagi memiliki akses ke proyek. |
| 404 | invoice_not_found | Tidak ada faktur dengan ID publik tersebut dalam proyek yang diotorisasi, atau checkout tidak bisa menampilkannya. |
| 404 | payment_resource_not_found | Proyek, toko, aset, atau dompet yang diperlukan saat menyiapkan faktur tidak lagi ada. |
| 404 | token_candidate_not_found | Proyek tidak tersedia atau token tidak lagi ada dalam katalog penemuan cocok saat ini. |
| 409 | idempotency_conflict | Kunci dengan cakupan toko sudah ada dan kredensial atau byte permintaan mentah persis berbeda. |
| 409 | store_unavailable | Proyek/toko dinonaktifkan atau tidak tersedia. |
| 409 | no_ready_payment_methods | Tidak ada metode toko yang siap. Baca error.message dan error.details.payment_methods untuk chain_slug, asset_ticker, dan reason_code. Cadangan/aktivasi dompet, adapter terinstal, dan harga harus valid. Mulai 6.0.6, masa tunggu pemindai, pemeriksaan kesehatan gagal atau usang, serta kuorum penyedia yang belum terpenuhi tidak memblokir pembuatan. |
| 409 | payment_method_unavailable | Metode yang dipilih menjadi tidak tersedia saat pemeriksaan ulang atomik pada pembuatan. |
| 409 | store_payment_method_not_selected | Pengesampingan konfirmasi toko diminta untuk aset yang saat ini tidak dipilih toko tersebut. |
| 409 | wallet_unavailable | Dompet pembayaran menjadi tidak tersedia saat pemeriksaan ulang atomik pada pembuatan. |
| 409 | ipn_secret_required | URL IPN efektif ada, tetapi toko tidak memiliki rahasia penandatanganan IPN. |
| 409 | payment_resource_not_ready | Aset pembayaran atau dompet yang diperlukan dinonaktifkan, belum dicadangkan, menunggu bukti aktivasi akun bersama, habis, atau belum siap karena alasan lain. |
| 409 | account_activation_unverified | Aktivasi akun XRP Ledger atau Stellar tidak bisa dibuktikan melalui jumlah endpoint mainnet sehat yang dikonfigurasi (bawaan 2, opsional 1); danai akun yang tepat dan coba ulang verifikasi. |
| 400 | invalid_monero_wallet_rpc | Endpoint HTTPS, alamat utama mainnet persis, label, atau input autentikasi Digest/Basic/header lengkap tidak valid. |
| 404 | monero_wallet_rpc_not_found | Ikatan wallet-RPC Monero dengan cakupan proyek tidak ada. |
| 409 | monero_wallet_rpc_not_ready | Aset Monero, kuorum dua daemon, ikatan yang tidak dapat diubah, atau pernyataan cadangan/hanya lihat eksplisit belum siap. |
| 409 | monero_wallet_rpc_unavailable | Pembuatan faktur memerlukan ikatan wallet-RPC Monero proyek yang aktif, terverifikasi, dan telah dinyatakan, dengan kredensial sisi server valid. |
| 503 | lightning_unavailable | Satu-satunya metode toko yang siap adalah Lightning dan dompet atau kuotasinya tidak bisa diverifikasi. Coba lagi dengan kunci idempotensi yang sama. Jika ada metode on-chain lain yang siap, metode Lightning yang tidak tersedia dihilangkan. |
| 422 | monero_wallet_rpc_verification_failed | Dompet persis, pinning HTTPS, sinkronisasi, kuorum daemon mainnet, atau bukti penolakan metode gateway gagal. |
| 503 | monero_wallet_rpc_failed | wallet-RPC hanya pantau eksternal tidak bisa menyiapkan dan membaca ulang subalamat faktur dengan aman; tidak ada alamat cadangan yang direkayasa. |
| 409 | token_chain_not_ready | Aset blockchain native dinonaktifkan, pemetaan penemuan berubah saat verifikasi, atau proyek sudah memiliki maksimum saat ini sebanyak 20 aset token terdaftar. |
| 503 | dex_price_unavailable | Penyedia DEX tidak tersedia, sibuk, dibatasi permintaan, memberikan respons usang, atau data salah format. Coba lagi setelah satu menit; harga tetap masih tersedia. |
| 422 | invalid_dex_price | Kombinasi mode harga tidak valid atau pool yang dipilih tidak bisa menyediakan harga yang memenuhi syarat untuk kontrak persis. Pilih pool lain atau harga USD tetap. |
| 422 | token_verification_failed | Setiap node yang memenuhi syarat gagal memverifikasi identitas blockchain, kode kontrak, desimal, kueri saldo, atau mint. |
| 422 | invalid_store_confirmation_policy | Pengesampingan toko tidak tersedia untuk mode finalitas ini, berada di luar batas khusus blockchain yang dikembalikan, atau meminta penerimaan nol konfirmasi yang tidak didukung. |
| 409 | invoice_not_payable | Faktur checkout berada pada status akhir atau tenggat pembayarannya telah berlalu. |
| 409 | invoice_payment_method_locked | Pembayaran valid sudah memilih aset lain; lanjutkan dengan active_payment_method_id. |
| 409 | payment_method_not_payable | Metode yang dipilih sudah selesai atau tidak lagi menerima pembayaran lain. |
| 422 | payment_qr_unavailable | Permintaan pembayaran checkout terlalu besar untuk dienkode sebagai gambar QR SVG. |
| 503 | payment_rates_unavailable | Tidak ada kuotasi terbaru yang tepercaya untuk metode pembayaran siap mana pun. |
| 500 | authentication_unavailable | Autentikasi bearer tidak bisa membaca atau memvalidasi kredensial tersimpannya dengan aman. |
| 429 | rate_limit_exceeded | Kredensial ini telah menghabiskan jatah menit UTC saat ini. Tunggu setidaknya sejumlah detik Retry-After; coba ulang pembuatan faktur dengan kunci idempotensi yang sama. |
| 500 | database_error / internal_error | Kegagalan sementara sisi server; coba ulang dengan aman menggunakan kunci idempotensi yang sama. |
Ikhtisar API
Pilih endpoint untuk melihat kolom, contoh, dan responsnya.
Faktur
POSTBuat faktur/v1/projects/{project_id}/stores/{store_id}/invoicesGETDaftar faktur/v1/projects/{project_id}/invoicesGETAmbil faktur/v1/projects/{project_id}/invoices/{invoice_id}GETDaftar pembayaran faktur/v1/projects/{project_id}/invoices/{invoice_id}/paymentsMetode pembayaran
GETDaftar aset pembayaran proyek/v1/projects/{project_id}/payment-assetsPUTPerbarui kebijakan aset proyek/v1/projects/{project_id}/payment-assets/{asset_id}GETJelajahi kandidat token pembayaran/v1/projects/{project_id}/payment-token-candidatesPOSTVerifikasi dan daftarkan token/v1/projects/{project_id}/payment-token-assetsGETTemukan pool DEX token kustom/v1/projects/{project_id}/payment-token-dex-poolsPOSTTambahkan atau ubah harga token kustom/v1/projects/{project_id}/payment-token-assets/customGETDaftar metode pembayaran toko/v1/projects/{project_id}/stores/{store_id}/payment-assetsPUTGanti metode pembayaran toko/v1/projects/{project_id}/stores/{store_id}/payment-assetsPUTTetapkan kebijakan konfirmasi toko/v1/projects/{project_id}/stores/{store_id}/payment-assets/{asset_id}/confirmation-policyDompet
GETDaftar dompet dan saldo proyek/v1/projects/{project_id}/walletsRekonsiliasi
GETDaftar pengecualian pembayaran/v1/projects/{project_id}/reconciliationGETBaca bukti rekonsiliasi/v1/projects/{project_id}/reconciliation/{invoice_id}API Marketplace
GETKemampuan/v1/marketplace/capabilitiesGETLaporan Marketplace/v1/marketplace/overviewGETPengaturan proyek/v1/marketplace/settingsPOSTSimpan pengaturan proyek/v1/marketplace/settingsGETDaftar vendor/v1/marketplace/vendorsPOSTBuat vendor/v1/marketplace/vendorsGETAmbil vendor/v1/marketplace/vendors/{vendor_id}POSTPerbarui vendor/v1/marketplace/vendors/{vendor_id}/updatePOSTArsipkan vendor/v1/marketplace/vendors/{vendor_id}/archiveGETTujuan vendor/v1/marketplace/vendors/{vendor_id}/destinationsPOSTTambahkan tujuan pembayaran/v1/marketplace/vendors/{vendor_id}/destinationsPOSTSetujui tujuan/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/approvePOSTNonaktifkan tujuan/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/disableGETSaldo vendor/v1/marketplace/vendors/{vendor_id}/balancesGETFaktur Marketplace/v1/marketplace/invoicesPOSTBuat faktur multivendor/v1/marketplace/invoicesGETFaktur dan alokasi/v1/marketplace/invoices/{invoice_id}GETBukti pembayaran faktur/v1/marketplace/invoices/{invoice_id}/paymentsGETAlokasi faktur/v1/marketplace/invoices/{invoice_id}/allocationsPOSTBatalkan faktur belum dibayar/v1/marketplace/invoices/{invoice_id}/cancelPOSTTahan alokasi/v1/marketplace/invoices/{invoice_id}/allocations/holdPOSTTinjau dan lepaskan alokasi/v1/marketplace/invoices/{invoice_id}/allocations/releasePOSTTautkan ulang tujuan yang belum dibayar/v1/marketplace/invoices/{invoice_id}/allocations/{allocation_id}/destinationPOSTSiapkan pengembalian dana penuh/v1/marketplace/invoices/{invoice_id}/refundGETTemukan alokasi pembayaran/v1/marketplace/allocationsGETSaldo buku besar proyek/v1/marketplace/balancesGETJurnal yang tidak dapat diubah/v1/marketplace/ledgerGETRiwayat pembayaran/v1/marketplace/payoutsPOSTPratinjau rencana alokasi/v1/marketplace/payouts/previewPOSTSiapkan pembayaran/v1/marketplace/payoutsGETDetail pembayaran/v1/marketplace/payouts/{payout_id}POSTSetujui dan kirim/v1/marketplace/payouts/{payout_id}/approvePOSTTinjau dan lanjutkan pembayaran/v1/marketplace/payouts/{payout_id}/resumePOSTBatalkan pekerjaan yang belum ditandatangani/v1/marketplace/payouts/{payout_id}/cancelGETKebijakan pembayaran otomatis/v1/marketplace/policiesPOSTOtorisasi kebijakan pembayaran/v1/marketplace/policiesGETWebhook Marketplace/v1/marketplace/webhooksPOSTBuat webhook Marketplace/v1/marketplace/webhooksPOSTPerbarui webhook Marketplace/v1/marketplace/webhooks/{webhook_id}/updatePOSTNonaktifkan webhook Marketplace/v1/marketplace/webhooks/{webhook_id}/disableGETPeristiwa Marketplace/v1/marketplace/eventsGETBaca peristiwa tersimpan/v1/marketplace/events/{event_id}GETRiwayat pengiriman Marketplace/v1/marketplace/webhook-deliveriesGETDetail pengiriman/v1/marketplace/webhook-deliveries/{delivery_id}POSTKirim ulang peristiwa yang sama/v1/marketplace/webhook-deliveries/{delivery_id}/resendAPI Operator
GETKemampuan/v1/operator/capabilitiesGETKesehatan/v1/operator/healthGETDaftar Merchant/v1/operator/merchantsPOSTBuat Merchant/v1/operator/merchantsGETAmbil Merchant/v1/operator/merchants/{merchant_id}POSTPerbarui Merchant/v1/operator/merchants/{merchant_id}GETDaftar Pengguna/v1/operator/merchants/{merchant_id}/usersPOSTBuat Pengguna/v1/operator/merchants/{merchant_id}/usersGETAmbil Pengguna/v1/operator/merchants/{merchant_id}/users/{user_id}POSTPerbarui Pengguna/v1/operator/merchants/{merchant_id}/users/{user_id}POSTTetapkan Kata Sandi Pengguna/v1/operator/merchants/{merchant_id}/users/{user_id}/passwordPOSTCabut Sesi Pengguna/v1/operator/merchants/{merchant_id}/users/{user_id}/revoke-sessionsGETDaftar Undangan/v1/operator/merchants/{merchant_id}/invitationsPOSTBuat Undangan/v1/operator/merchants/{merchant_id}/invitationsGETAmbil Undangan/v1/operator/invitations/{invitation_id}POSTKirim Ulang Undangan/v1/operator/invitations/{invitation_id}/resendPOSTCabut Undangan/v1/operator/invitations/{invitation_id}/revokeGETAmbil Kredit/v1/operator/merchants/{merchant_id}/creditsGETDaftar Buku Besar Kredit/v1/operator/merchants/{merchant_id}/credits/ledgerPOSTSesuaikan Kredit/v1/operator/merchants/{merchant_id}/credits/adjustmentsGETDaftar Isi Ulang/v1/operator/merchants/{merchant_id}/topupsPOSTBuat Isi Ulang/v1/operator/merchants/{merchant_id}/topupsGETAmbil Isi Ulang/v1/operator/merchants/{merchant_id}/topups/{topup_id}GETLaporan/v1/operator/reportsGETDaftar Audit/v1/operator/auditGETDaftar Peristiwa/v1/operator/eventsGETDaftar Webhook/v1/operator/webhooksPOSTBuat Webhook/v1/operator/webhooksPOSTPerbarui Webhook/v1/operator/webhooks/{webhook_id}POSTRotasi Rahasia Webhook/v1/operator/webhooks/{webhook_id}/rotateGETDaftar Pengiriman Webhook/v1/operator/webhooks/{webhook_id}/deliveriesGETDaftar Proyek/v1/operator/merchants/{merchant_id}/projectsPOSTBuat Proyek/v1/operator/merchants/{merchant_id}/projectsGETAmbil Proyek/v1/operator/merchants/{merchant_id}/projects/{project_id}POSTPerbarui Proyek/v1/operator/merchants/{merchant_id}/projects/{project_id}GETDaftar Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesPOSTBuat Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesGETAmbil Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}POSTPerbarui Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}GETAmbil Tampilan Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearancePOSTPerbarui Tampilan Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearanceGETDaftar Aset Pembayaran Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsPOSTPerbarui Aset Pembayaran Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsGETDaftar Webhook Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksPOSTBuat Webhook Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksPOSTPerbarui Webhook Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooks/{webhook_id}GETDaftar Faktur/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoicesGETAmbil Faktur/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoices/{invoice_id}GETDaftar Dompet/v1/operator/merchants/{merchant_id}/projects/{project_id}/walletsGETDaftar Alamat Dompet/v1/operator/merchants/{merchant_id}/projects/{project_id}/wallets/{wallet_id}/addressesGETDaftar Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentialsPOSTBuat Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentialsPOSTPerbarui Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}POSTRotasi Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/rotatePOSTCabut Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/revokePOSTPeriksa token undangan/v1/onboarding/invitations/checkPOSTTerima undangan atau reset kata sandi/v1/onboarding/invitations/acceptCheckout
GETKerangka checkout/GETHalaman checkout yang dihosting/invoice/{invoice_id}GETFaktur yang aman untuk checkout/checkout-api/invoices/{invoice_id}GETPratinjau checkout toko/invoice/preview/{project_id}GETData pratinjau checkout/checkout-api/previews/{project_id}GETGambar checkout toko/checkout-api/invoices/{invoice_id}/appearance-images/{kind}/{revision}/image.pngGETGambar pratinjau toko/checkout-api/previews/{project_id}/stores/{store_id}/appearance-images/{kind}/{revision}/image.pngGETLogo pratinjau dengan revisi/checkout-api/previews/{project_id}/logo/{revision}/image.pngGETGambar QR pembayaran/checkout-api/invoices/{invoice_id}/payment-methods/{intent_id}/qr.svgGETLogo checkout dengan revisi/checkout-api/invoices/{invoice_id}/logo/{revision}/image.pngLayanan
GETPenemuan layanan API/GETKesehatan layanan/healthzGETKemampuan/v1/operator/capabilitiesHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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
}Kolom respons
Catatan penggunaan
- Memerlukan health.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETKesehatan/v1/operator/healthHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"version": "7.4.0",
"nodes": []
}Kolom respons
Catatan penggunaan
- Memerlukan health.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Merchant/v1/operator/merchantsHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan merchants.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTBuat Merchant/v1/operator/merchantsBaca + tulis
Buat merchant yang dihosting dan administrator pertama secara atomik, langsung dengan kata sandi atau melalui undangan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Permintaan
: "${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))Body permintaan
onboardingdirect | invitationwajibdirect memerlukan password, tidak mengirim email undangan. invitation tidak menyertakan password.
passwordstring · direct only12–128 karakter (paling banyak 512 byte UTF-8); tidak pernah dikembalikan atau dikirim melalui email. Gunakan require_password_change untuk kata sandi sementara.
require_password_changebooleanopsionalMemerlukan kata sandi baru saat login pertama. Setiap akun yang disiapkan langsung harus mengakui kustodi dompet oleh host.
currencyfiat codeopsionalMata uang akun prabayar; bawaan mengikuti mata uang regional dan tidak bisa diubah kemudian.
fee_bpsintegeropsional0–10000; 100 berarti 1%. Menggunakan pengaturan bawaan operator jika tidak disertakan. Memerlukan fees.write.
starting_creditdecimal stringopsionalPemberian lokal presisi satu kali. Nilai bukan nol memerlukan credits.write. Tidak mengisi ulang saldo instalasi operator.
send_invitation_emailbooleanopsionalKhusus undangan. Memerlukan SMTP yang dikonfigurasi; respons membedakan penerimaan relay dari pembuatan akun.
Respons 201 or 200 application/json
Contoh respons
{
"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
}Kolom respons
Catatan penggunaan
- Memerlukan merchants.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Akses merchant global diperlukan. Pengesampingan biaya eksplisit juga memerlukan fees.write; starting_credit bukan nol memerlukan credits.write. Pendaftaran melalui undangan juga memerlukan invitations.write. Tanpa login otomatis, tanpa melewati Basic Auth, tanpa kredit retroaktif saat percobaan ulang.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETAmbil Merchant/v1/operator/merchants/{merchant_id}Hanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan merchants.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPerbarui Merchant/v1/operator/merchants/{merchant_id}Baca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
namefieldsopsionalPenonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.Detail
Penonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.
enabledfieldsopsionalPenonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.Detail
Penonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.
payments_pausedfieldsopsionalPenonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.Detail
Penonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.
fee_bpsfieldsopsionalPenonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.Detail
Penonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.
external_idfieldsopsionalPenonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.Detail
Penonaktifan mencabut sesi. payments_paused memblokir faktur baru, bukan pemindaian pembayaran yang ada. Perubahan biaya memerlukan fees.write dan memengaruhi faktur mendatang; mata uang akun tidak bisa berubah.
Respons 200 application/json
Contoh respons
{
"id": "11111111-1111-4111-8111-111111111111",
"name": "Example shop",
"currency": "EUR",
"balance": "10",
"fee_bps": 300,
"enabled": true,
"payments_paused": false
}Kolom respons
Catatan penggunaan
- Memerlukan merchants.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Pengguna/v1/operator/merchants/{merchant_id}/usersHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan users.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTBuat Pengguna/v1/operator/merchants/{merchant_id}/usersBaca + tulis
Tambahkan administrator merchant atau pengguna yang dibatasi ke proyek tertentu.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
require_password_changesame as merchant creationPembuatan undangan juga memerlukan invitations.write.
send_invitation_emailsame as merchant creationPembuatan undangan juga memerlukan invitations.write.
access_leveladmin | projectsopsionaladmin hanya administrator merchant ini, tidak pernah administrator instalasi/operator.
project_ids[]UUID[]Hanya proyek milik merchant. Pilihan wajib untuk akses terbatas proyek; tidak pernah lintas tenant.
Respons 201 or 200 application/json
Contoh respons
{
"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"
}Kolom respons
userobject
user_idstringaccess_linkJSON | nullmerchant_idstringCatatan penggunaan
- Memerlukan users.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETAmbil Pengguna/v1/operator/merchants/{merchant_id}/users/{user_id}Hanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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
}Kolom respons
Catatan penggunaan
- Memerlukan users.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPerbarui Pengguna/v1/operator/merchants/{merchant_id}/users/{user_id}Baca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
Permintaan
: "${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))Body permintaan
emailfieldsopsionalMemperbarui kolom yang diberikan; perlindungan admin terakhir tetap berlaku. Kata sandi memiliki operasi users.security terpisah.
display_namefieldsopsionalMemperbarui kolom yang diberikan; perlindungan admin terakhir tetap berlaku. Kata sandi memiliki operasi users.security terpisah.
enabledfieldsopsionalMemperbarui kolom yang diberikan; perlindungan admin terakhir tetap berlaku. Kata sandi memiliki operasi users.security terpisah.
access_levelfieldsopsionalMemperbarui kolom yang diberikan; perlindungan admin terakhir tetap berlaku. Kata sandi memiliki operasi users.security terpisah.
project_idsfieldsopsionalMemperbarui kolom yang diberikan; perlindungan admin terakhir tetap berlaku. Kata sandi memiliki operasi users.security terpisah.
default_timezonefieldsopsionalMemperbarui kolom yang diberikan; perlindungan admin terakhir tetap berlaku. Kata sandi memiliki operasi users.security terpisah.
Respons 200 application/json
Contoh respons
{
"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
}Kolom respons
Catatan penggunaan
- Memerlukan users.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTTetapkan Kata Sandi Pengguna/v1/operator/merchants/{merchant_id}/users/{user_id}/passwordBaca + tulis
Tetapkan kata sandi akun yang dihosting dan cabut sesi. TOTP yang ada dipertahankan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"user_id": "11111111-1111-4111-8111-111111111111",
"sessions_revoked": true,
"totp_preserved": true
}Kolom respons
Catatan penggunaan
- Memerlukan users.security; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTCabut Sesi Pengguna/v1/operator/merchants/{merchant_id}/users/{user_id}/revoke-sessionsBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"user_id": "11111111-1111-4111-8111-111111111111",
"sessions_revoked": true,
"totp_preserved": true
}Kolom respons
Catatan penggunaan
- Memerlukan users.security; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Undangan/v1/operator/merchants/{merchant_id}/invitationsHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan invitations.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTBuat Undangan/v1/operator/merchants/{merchant_id}/invitationsBaca + tulis
Buat atau ganti tautan undangan atau reset kata sandi sekali pakai.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
user_idUUID, booleanTerbitkan/ganti tautan sekali pakai untuk akun yang ada. Pengguna aktif menerima tautan reset satu jam dan memerlukan users.security.
send_emailUUID, booleanTerbitkan/ganti tautan sekali pakai untuk akun yang ada. Pengguna aktif menerima tautan reset satu jam dan memerlukan users.security.
new user fieldsalternative to user_idGunakan email, display_name, access_level, dan project_ids untuk membuat pengguna yang diundang; memerlukan users.write.
Respons 201 or 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan invitations.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETAmbil Undangan/v1/operator/invitations/{invitation_id}Hanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
invitation_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan invitations.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTKirim Ulang Undangan/v1/operator/invitations/{invitation_id}/resendBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
invitation_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
send_emailbooleanopsionalMengganti token sebelumnya, tidak pernah menambah kredit. Mengembalikan tautan baru yang dihasilkan satu kali. Akun yang sudah aktif memerlukan users.security.
Respons 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan invitations.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTCabut Undangan/v1/operator/invitations/{invitation_id}/revokeBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
invitation_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"revoked": true,
"invitation_id": "44444444-4444-4444-8444-444444444444"
}Kolom respons
Catatan penggunaan
- Memerlukan invitations.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETAmbil Kredit/v1/operator/merchants/{merchant_id}/creditsHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan credits.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Buku Besar Kredit/v1/operator/merchants/{merchant_id}/credits/ledgerHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
qopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan credits.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTSesuaikan Kredit/v1/operator/merchants/{merchant_id}/credits/adjustmentsBaca + tulis
Tambahkan pemberian atau koreksi beserta alasan ke buku besar prabayar merchant ini.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
amountsigned decimal stringwajibPemberian positif atau koreksi negatif, hingga enam desimal dalam mata uang kredit merchant. Bukan transfer on-chain.
Respons 200 application/json
Contoh respons
{
"balance": "25"
}Kolom respons
balancestringCatatan penggunaan
- Memerlukan credits.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Isi Ulang/v1/operator/merchants/{merchant_id}/topupsHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan topups.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTBuat Isi Ulang/v1/operator/merchants/{merchant_id}/topupsBaca + tulis
Buat checkout untuk kredit prabayar; jangan pernah menandainya lunas secara manual.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
Respons 201 or 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan topups.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETAmbil Isi Ulang/v1/operator/merchants/{merchant_id}/topups/{topup_id}Hanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan topups.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETLaporan/v1/operator/reportsHanya baca
Baca ikhtisar keuangan Operator. Memerlukan akses ke semua merchant yang dihosting.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter kueri
periodopsionalFilter keuangan. period bawaan last30; gunakan custom dengan start/end YYYY-MM-DD. Hanya kredensial semua merchant.
startopsionalFilter keuangan. period bawaan last30; gunakan custom dengan start/end YYYY-MM-DD. Hanya kredensial semua merchant.
endopsionalFilter keuangan. period bawaan last30; gunakan custom dengan start/end YYYY-MM-DD. Hanya kredensial semua merchant.
currencyopsionalFilter keuangan. period bawaan last30; gunakan custom dengan start/end YYYY-MM-DD. Hanya kredensial semua merchant.
merchant_idopsionalFilter keuangan. period bawaan last30; gunakan custom dengan start/end YYYY-MM-DD. Hanya kredensial semua merchant.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan reports.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Baris, biaya, dan hitungan bisnis sendiri dikecualikan sebelum total dihitung. Filter merchant_id bisnis sendiri mengembalikan 404. Pelaporan menggunakan zona waktu instalasi.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Audit/v1/operator/auditHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter kueri
merchant_idopsionalFilter merchant yang diizinkan, jenis peristiwa persis (events), atau teks tindakan (audit). Peristiwa disimpan: 30 hari.
searchopsionalFilter merchant yang diizinkan, jenis peristiwa persis (events), atau teks tindakan (audit). Peristiwa disimpan: 30 hari.
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan audit.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Peristiwa/v1/operator/eventsHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter kueri
merchant_idopsionalFilter merchant yang diizinkan, jenis peristiwa persis (events), atau teks tindakan (audit). Peristiwa disimpan: 30 hari.
event_typeopsionalFilter merchant yang diizinkan, jenis peristiwa persis (events), atau teks tindakan (audit). Peristiwa disimpan: 30 hari.
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan events.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Webhook/v1/operator/webhooksHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan events.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTBuat Webhook/v1/operator/webhooksBaca + tulis
Berlangganan peristiwa siklus hidup Operator mendatang. Bukan webhook pembayaran toko.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Permintaan
: "${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))Body permintaan
urlpublic HTTPS URLwajibTanpa kredensial, IP privat, atau pengalihan. DNS/IP diperiksa kembali saat pengiriman.
merchant_ids[]UUID[]opsionalKosong berarti semua merchant yang diizinkan kredensial ini. Pembatasan cakupan terkini diperiksa ulang.
enabledbooleanopsionalEndpoint yang dijeda mempertahankan pengiriman dalam antrean; pengaktifan kembali melanjutkan pekerjaan valid yang tersimpan.
Respons 201 or 200 application/json
Contoh respons
{
"id": "11111111-1111-4111-8111-111111111111",
"signing_secret": "wco_whsec_EXAMPLE_ONLY_SAVE_ONCE"
}Kolom respons
Catatan penggunaan
- Memerlukan webhooks.write + events.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPerbarui Webhook/v1/operator/webhooks/{webhook_id}Baca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
webhook_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
urlpublic HTTPS URLwajibTanpa kredensial, IP privat, atau pengalihan. DNS/IP diperiksa kembali saat pengiriman.
merchant_ids[]UUID[]opsionalKosong berarti semua merchant yang diizinkan kredensial ini. Pembatasan cakupan terkini diperiksa ulang.
enabledbooleanopsionalEndpoint yang dijeda mempertahankan pengiriman dalam antrean; pengaktifan kembali melanjutkan pekerjaan valid yang tersimpan.
Respons 200 application/json
Contoh respons
{
"id": "44444444-4444-4444-8444-444444444444",
"signing_secret": null
}Kolom respons
Catatan penggunaan
- Memerlukan webhooks.write + events.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTRotasi Rahasia Webhook/v1/operator/webhooks/{webhook_id}/rotateBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
webhook_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"id": "11111111-1111-4111-8111-111111111111",
"signing_secret": "wco_whsec_EXAMPLE_ONLY_SAVE_ONCE"
}Kolom respons
Catatan penggunaan
- Memerlukan webhooks.write + events.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Pengiriman Webhook/v1/operator/webhooks/{webhook_id}/deliveriesHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
webhook_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan events.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Proyek/v1/operator/merchants/{merchant_id}/projectsHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan projects.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTBuat Proyek/v1/operator/merchants/{merchant_id}/projectsBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
namestringswajibNama dan pengenal proyek stabil yang unik. Membuat dompet lokal menggunakan bootstrap proyek yang ada, tidak pernah mentransfer dana.
slugstringswajibNama dan pengenal proyek stabil yang unik. Membuat dompet lokal menggunakan bootstrap proyek yang ada, tidak pernah mentransfer dana.
enabledopsionalenabled bawaan true; disarankan membuat dalam keadaan dijeda dan mengonfigurasi toko terlebih dahulu.
reporting_timezoneopsionalenabled bawaan true; disarankan membuat dalam keadaan dijeda dan mengonfigurasi toko terlebih dahulu.
checkout_titleopsionalenabled bawaan true; disarankan membuat dalam keadaan dijeda dan mengonfigurasi toko terlebih dahulu.
checkout_descriptionopsionalenabled bawaan true; disarankan membuat dalam keadaan dijeda dan mengonfigurasi toko terlebih dahulu.
checkout_themeopsionalenabled bawaan true; disarankan membuat dalam keadaan dijeda dan mengonfigurasi toko terlebih dahulu.
checkout_accent_coloropsionalenabled bawaan true; disarankan membuat dalam keadaan dijeda dan mengonfigurasi toko terlebih dahulu.
Respons 201 or 200 application/json
Contoh respons
{
"id": "33333333-3333-4333-8333-333333333333",
"slug": "example-shop",
"name": "Example shop",
"enabled": false,
"reporting_currency": "EUR",
"reporting_timezone": "Europe/Berlin",
"stores": []
}Kolom respons
Catatan penggunaan
- Memerlukan projects.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETAmbil Proyek/v1/operator/merchants/{merchant_id}/projects/{project_id}Hanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"id": "33333333-3333-4333-8333-333333333333",
"slug": "example-shop",
"name": "Example shop",
"enabled": false,
"reporting_currency": "EUR",
"reporting_timezone": "Europe/Berlin",
"stores": []
}Kolom respons
Catatan penggunaan
- Memerlukan projects.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPerbarui Proyek/v1/operator/merchants/{merchant_id}/projects/{project_id}Baca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
Permintaan
: "${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))Body permintaan
checkout_descriptionopsionalPembaruan parsial. Pengenal dan kepemilikan merchant tidak bisa berubah.
checkout_accent_coloropsionalPembaruan parsial. Pengenal dan kepemilikan merchant tidak bisa berubah.
Respons 200 application/json
Contoh respons
{
"id": "33333333-3333-4333-8333-333333333333",
"slug": "example-shop",
"name": "Example shop",
"enabled": false,
"reporting_currency": "EUR",
"reporting_timezone": "Europe/Berlin",
"stores": []
}Kolom respons
Catatan penggunaan
- Memerlukan projects.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan projects.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTBuat Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/storesBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
Permintaan
: "${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))Body permintaan
default_currencyopsionalGunakan string desimal untuk persentase. Toko baru mewarisi tampilan toko bawaan proyek.
invoice_expiry_minutesopsionalGunakan string desimal untuk persentase. Toko baru mewarisi tampilan toko bawaan proyek.
exchange_rate_spread_percentopsionalGunakan string desimal untuk persentase. Toko baru mewarisi tampilan toko bawaan proyek.
underpayment_tolerance_percentopsionalGunakan string desimal untuk persentase. Toko baru mewarisi tampilan toko bawaan proyek.
enabledopsionalKonfigurasikan aset yang diterima dengan payment-assets; faktur bernilai nol nonaktif secara bawaan.
is_defaultopsionalKonfigurasikan aset yang diterima dengan payment-assets; faktur bernilai nol nonaktif secara bawaan.
allow_zero_amount_invoicesopsionalKonfigurasikan aset yang diterima dengan payment-assets; faktur bernilai nol nonaktif secara bawaan.
allow_underpaymentsopsionalKonfigurasikan aset yang diterima dengan payment-assets; faktur bernilai nol nonaktif secara bawaan.
allow_overpaymentsopsionalKonfigurasikan aset yang diterima dengan payment-assets; faktur bernilai nol nonaktif secara bawaan.
allowed_chain_slugsopsionalKonfigurasikan aset yang diterima dengan payment-assets; faktur bernilai nol nonaktif secara bawaan.
ipn_enabledopsionalURL IPN dan kembali mengikuti validasi URL yang ada. Tanpa HTML/JavaScript sembarang.
default_ipn_urlopsionalURL IPN dan kembali mengikuti validasi URL yang ada. Tanpa HTML/JavaScript sembarang.
default_redirect_urlopsionalURL IPN dan kembali mengikuti validasi URL yang ada. Tanpa HTML/JavaScript sembarang.
default_cancel_urlopsionalURL IPN dan kembali mengikuti validasi URL yang ada. Tanpa HTML/JavaScript sembarang.
redirect_automaticallyopsionalURL IPN dan kembali mengikuti validasi URL yang ada. Tanpa HTML/JavaScript sembarang.
checkout_languageopsionalGunakan bahasa yang didukung dan domain peran aktif; konfigurasikan origin penyematan secara eksplisit.
embed_enabledopsionalGunakan bahasa yang didukung dan domain peran aktif; konfigurasikan origin penyematan secara eksplisit.
allowed_embed_originsopsionalGunakan bahasa yang didukung dan domain peran aktif; konfigurasikan origin penyematan secara eksplisit.
domainsopsionalGunakan bahasa yang didukung dan domain peran aktif; konfigurasikan origin penyematan secara eksplisit.
Respons 201 or 200 application/json
Contoh respons
{
"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
}Kolom respons
Catatan penggunaan
- Memerlukan projects.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETAmbil Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}Hanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
store_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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
}Kolom respons
Catatan penggunaan
- Memerlukan projects.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPerbarui Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}Baca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
store_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"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
}Kolom respons
Catatan penggunaan
- Memerlukan projects.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETAmbil Tampilan Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearanceHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
store_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"revision": 1,
"settings": {
"inherit_default_store": true
},
"effective": {
"title": "Pay securely"
}
}Kolom respons
Catatan penggunaan
- Memerlukan projects.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPerbarui Tampilan Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/checkout-appearanceBaca + tulis
Simpan desain toko yang tervalidasi dan dilindungi revisi.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
store_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
revisionintegerwajibBaca revisi terkini dengan GET terlebih dahulu. Revisi usang gagal tanpa menimpa perubahan editor lain.
settingsobjectwajib
Tampilan checkout tervalidasi, termasuk inherit_default_store, merek, intro/outro, ukuran font, dan visibilitas. Tanpa HTML/JavaScript sembarang. Mengunggah byte gambar hanya melalui konsol.Detail
Tampilan checkout tervalidasi, termasuk inherit_default_store, merek, intro/outro, ukuran font, dan visibilitas. Tanpa HTML/JavaScript sembarang. Mengunggah byte gambar hanya melalui konsol.
Respons 200 application/json
Contoh respons
{
"settings": {
"inherit_default_store": false,
"title": "Pay securely",
"theme": "light"
},
"revision": 2
}Kolom respons
Catatan penggunaan
- Memerlukan projects.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Aset Pembayaran Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
store_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": []
}Kolom respons
data[]arrayCatatan penggunaan
- Memerlukan projects.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPerbarui Aset Pembayaran Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/payment-assetsBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
store_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
assets[]object[]wajib
Penggantian penuh metode on-chain: UUID asset_id dan display_order. [] menghapus aset on-chain yang diterima. Hanya aset proyek terverifikasi; tidak mengonfigurasi Lightning.Detail
Penggantian penuh metode on-chain: UUID asset_id dan display_order. [] menghapus aset on-chain yang diterima. Hanya aset proyek terverifikasi; tidak mengonfigurasi Lightning.
Respons 200 application/json
Contoh respons
{
"data": []
}Kolom respons
data[]arrayCatatan penggunaan
- Memerlukan projects.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Webhook Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
store_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan projects.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTBuat Webhook Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooksBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
store_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
namestrings / arraywajibPenerima HTTPS publik dan nama peristiwa faktur dari dokumentasi IPN & webhook.
urlstrings / arraywajibPenerima HTTPS publik dan nama peristiwa faktur dari dokumentasi IPN & webhook.
event_types[]strings / arraywajibPenerima HTTPS publik dan nama peristiwa faktur dari dokumentasi IPN & webhook.
enabledbooleansopsionalPembuatan mengembalikan rahasia penandatanganan satu kali. Ini callback pembayaran toko, bukan peristiwa siklus hidup Operator.
automatic_redeliverybooleansopsionalPembuatan mengembalikan rahasia penandatanganan satu kali. Ini callback pembayaran toko, bukan peristiwa siklus hidup Operator.
Respons 201 or 200 application/json
Contoh respons
{
"signing_secret": "EXAMPLE_ONLY_SAVE_ONCE",
"endpoint": {
"id": "44444444-4444-4444-8444-444444444444",
"name": "Orders",
"enabled": true
},
"secret_visible_once": true
}Kolom respons
Catatan penggunaan
- Memerlukan projects.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPerbarui Webhook Toko/v1/operator/merchants/{merchant_id}/projects/{project_id}/stores/{store_id}/webhooks/{webhook_id}Baca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
store_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
webhook_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
namestrings / arraywajibPenerima HTTPS publik dan nama peristiwa faktur dari dokumentasi IPN & webhook.
urlstrings / arraywajibPenerima HTTPS publik dan nama peristiwa faktur dari dokumentasi IPN & webhook.
event_types[]strings / arraywajibPenerima HTTPS publik dan nama peristiwa faktur dari dokumentasi IPN & webhook.
enabledbooleansopsionalPembuatan mengembalikan rahasia penandatanganan satu kali. Ini callback pembayaran toko, bukan peristiwa siklus hidup Operator.
automatic_redeliverybooleansopsionalPembuatan mengembalikan rahasia penandatanganan satu kali. Ini callback pembayaran toko, bukan peristiwa siklus hidup Operator.
Respons 200 application/json
Contoh respons
{
"id": "44444444-4444-4444-8444-444444444444",
"name": "Orders",
"enabled": true
}Kolom respons
Catatan penggunaan
- Memerlukan projects.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Faktur/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoicesHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
Parameter kueri
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"pagination": {
"limit": 25,
"offset": 0,
"total": 0,
"has_more": false
}
}Kolom respons
Catatan penggunaan
- Memerlukan reports.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETAmbil Faktur/v1/operator/merchants/{merchant_id}/projects/{project_id}/invoices/{invoice_id}Hanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
invoice_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"invoice_id": "44444444-4444-4444-8444-444444444444",
"project_id": "33333333-3333-4333-8333-333333333333",
"amount": "25",
"currency": "EUR",
"status": "new",
"metadata": {},
"payment_intents": []
}Kolom respons
Catatan penggunaan
- Memerlukan reports.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
- invoice_id adalah ID faktur publik yang dikembalikan saat pembuatan dan dalam callback, bukan id internal.
Kesalahan
GETDaftar Dompet/v1/operator/merchants/{merchant_id}/projects/{project_id}/walletsHanya baca
Baca saldo dompet publik dalam cache, jangan pernah kunci privat atau frasa pemulihan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan reports.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Saldo adalah observasi dalam cache dengan kolom kebaruan, bukan jaminan saldo yang bisa dibelanjakan. Pengiriman dan ekspor kunci tidak tersedia melalui API ini.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Alamat Dompet/v1/operator/merchants/{merchant_id}/projects/{project_id}/wallets/{wallet_id}/addressesHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
project_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
wallet_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Parameter kueri
limitopsionalBatas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.Detail
Batas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.
beforeopsionalBatas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.Detail
Batas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.
searchopsionalBatas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.Detail
Batas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.
has_balanceopsionalBatas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.Detail
Batas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.
hide_small_balancesopsionalBatas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.Detail
Batas 1–50, bawaan 25. Kirim next_cursor sebagai before untuk halaman berikutnya. Jangan sertakan before untuk halaman 1. has_balance=false dan hide_small_balances=false menyertakan saldo kosong/kecil.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}
}Kolom respons
Catatan penggunaan
- Memerlukan reports.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETDaftar Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentialsHanya baca
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Parameter kueri
pageopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
searchopsionalHalaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.Detail
Halaman berbasis 1, 25 item per halaman. Pencarian didukung pada merchant, pengguna, proyek, toko, dompet, kredensial, dan webhook; daftar peristiwa native menggunakan filter khususnya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"page": 1,
"page_size": 25,
"total": 0
}Kolom respons
Catatan penggunaan
- Memerlukan merchant_credentials.read; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTBuat Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentialsBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
merchant_idUUIDwajibUUID resource kanonis huruf kecil; harus termasuk dalam cakupan merchant kredensial.
Permintaan
: "${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))Body permintaan
project_ids[]UUID[]Hanya proyek milik merchant yang dipilih; daftar kosong mengikuti kebijakan semua proyek merchant yang ada.
enabledopsionalKontrol kunci merchant yang ada. Rahasia dikembalikan hanya sekali; memerlukan merchant_credentials.write.
ip_restriction_enabledopsionalKontrol kunci merchant yang ada. Rahasia dikembalikan hanya sekali; memerlukan merchant_credentials.write.
allowed_ips[]opsionalKontrol kunci merchant yang ada. Rahasia dikembalikan hanya sekali; memerlukan merchant_credentials.write.
requests_per_minuteopsionalKontrol kunci merchant yang ada. Rahasia dikembalikan hanya sekali; memerlukan merchant_credentials.write.
Respons 201 or 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan merchant_credentials.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPerbarui Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}Baca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
Permintaan
: "${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))Body permintaan
namefieldswajibKirim konfigurasi kredensial terkini lengkap dengan perubahan. project_ids bawaan []; requests_per_minute bawaan mengikuti kuota API merchant.
access_levelfieldswajibKirim konfigurasi kredensial terkini lengkap dengan perubahan. project_ids bawaan []; requests_per_minute bawaan mengikuti kuota API merchant.
enabledfieldswajibKirim konfigurasi kredensial terkini lengkap dengan perubahan. project_ids bawaan []; requests_per_minute bawaan mengikuti kuota API merchant.
ip_restriction_enabledfieldswajibKirim konfigurasi kredensial terkini lengkap dengan perubahan. project_ids bawaan []; requests_per_minute bawaan mengikuti kuota API merchant.
allowed_ips[]fieldswajibKirim konfigurasi kredensial terkini lengkap dengan perubahan. project_ids bawaan []; requests_per_minute bawaan mengikuti kuota API merchant.
project_ids[]arrayRespons 200 application/json
Contoh respons
{
"id": "22222222-2222-4222-8222-222222222222",
"name": "Checkout",
"access_level": "read_only",
"project_ids": [
"33333333-3333-4333-8333-333333333333"
],
"enabled": true
}Kolom respons
Catatan penggunaan
- Memerlukan merchant_credentials.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTRotasi Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/rotateBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}Kolom respons
Catatan penggunaan
- Memerlukan merchant_credentials.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTCabut Kredensial Merchant/v1/operator/merchants/{merchant_id}/api-credentials/{credential_id}/revokeBaca + tulis
Kelola atau periksa resource merchant yang dihosting yang disebutkan menggunakan kredensial Operator terpisah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_OPERATOR_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; disimpan secara persisten untuk operasi ini |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"revoked": true
}Kolom respons
revokedbooleanCatatan penggunaan
- Memerlukan merchant_credentials.write; hanya merchant yang dihosting yang diizinkan. Kunci Operator tidak mengakses ruang kerja bisnis milik pemilik sendiri.
- Simpan Idempotency-Key unik dan body persis secara persisten sebelum mengirim. Percobaan ulang tidak pernah mengulangi tindakan yang sudah di-commit. Kolom rahasia dihilangkan pada replay; jika respons rahasia hilang, periksa resource yang dibuat dan rotasi/terbitkan ulang secara eksplisit. 409 operator_request_in_progress bisa berarti permintaan terputus dengan hasil tidak diketahui: periksa resource/audit; jangan sembarangan mencoba ulang dengan kunci baru.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTPeriksa token undangan/v1/onboarding/invitations/checkPublik
Pendaftaran hanya dengan token. Tidak menerima kunci Operator atau login otomatis. Login konsol tetap memerlukan Basic Auth situs dan TOTP yang ada.
Autentikasi & header
Publik
Permintaan
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))Body permintaan
Respons 200 application/json
Contoh respons
{
"kind": "invitation",
"email": "admin@example.test",
"merchant_name": "Example shop"
}Kolom respons
Catatan penggunaan
- Undangan 48 jam; tautan reset kata sandi satu jam. Token hash sekali pakai. Penerbitan ulang mencabut tautan sebelumnya. Penerimaan mempertahankan TOTP dan mencabut sesi lama.
- Tanpa percobaan ulang otomatis. Jika penerimaan melewati batas waktu, periksa status tautan dan coba login; jangan menganggapnya gagal. Dibatasi berdasarkan IP sumber teramati. Penerima harus memberikan pengakuan kustodinya sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
POSTTerima undangan atau reset kata sandi/v1/onboarding/invitations/acceptPublik
Pendaftaran hanya dengan token. Tidak menerima kunci Operator atau login otomatis. Login konsol tetap memerlukan Basic Auth situs dan TOTP yang ada.
Autentikasi & header
Publik
Permintaan
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))Body permintaan
Respons 200 application/json
Contoh respons
{
"password_set": true
}Kolom respons
password_setbooleanCatatan penggunaan
- Undangan 48 jam; tautan reset kata sandi satu jam. Token hash sekali pakai. Penerbitan ulang mencabut tautan sebelumnya. Penerimaan mempertahankan TOTP dan mencabut sesi lama.
- Tanpa percobaan ulang otomatis. Jika penerimaan melewati batas waktu, periksa status tautan dan coba login; jangan menganggapnya gagal. Dibatasi berdasarkan IP sumber teramati. Penerima harus memberikan pengakuan kustodinya sendiri.
- Contoh respons menampilkan kolom yang dipilih. Perlakukan kolom respons tambahan sebagai penambahan.
Kesalahan
GETKemampuan/v1/marketplace/capabilitiesHanya baca
Toko yang berpartisipasi, aset yang dikonfigurasi, jalur pembayaran vendor yang didukung, aset biaya native, dan alasan kesiapan. Ketersediaan pemindai sementara tidak memperluas kumpulan aset yang diizinkan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETLaporan Marketplace/v1/marketplace/overviewHanya baca
Filter store_id, asset_id, from, dan to (YYYY-MM-DD inklusif, UTC; bawaan 30 hari terakhir; hingga sepuluh tahun). Saldo akun presisi pada akhir tanggal dan perubahan dalam periode. Tanpa perkiraan pendapatan fiat. Filter toko mengecualikan biaya seluruh proyek yang tidak memiliki faktur.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETPengaturan proyek/v1/marketplace/settingsHanya baca
Mengembalikan enabled, payouts_paused, commission_percent, revision, dan toko yang berpartisipasi.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTSimpan pengaturan proyek/v1/marketplace/settingsBaca + tulis
Ganti pilihan toko yang berpartisipasi. revision 0 menginisialisasi pengaturan; perubahan selanjutnya memerlukan revisi yang dikembalikan. Komisi berupa persentase desimal, 0–100 dengan paling banyak dua angka desimal.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | policies.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan policies.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETDaftar vendor/v1/marketplace/vendorsHanya baca
Vendor berhalaman. Cari q berdasarkan nama, ID eksternal, atau email; status active, suspended, atau archived.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTBuat vendor/v1/marketplace/vendorsBaca + tulis
Nama wajib (160 karakter); external_id opsional dan unik dalam proyek (128); email opsional (254); description hingga 2000. commission_percent null mewarisi toko. Pengesampingan bukan null juga memerlukan commissions.override. Vendor bukan akun merchant yang dihosting.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | vendors.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan vendors.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETAmbil vendor/v1/marketplace/vendors/{vendor_id}Hanya baca
Kembalikan satu vendor, revisi, dan pengesampingan komisi.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTPerbarui vendor/v1/marketplace/vendors/{vendor_id}/updateBaca + tulis
Perbarui detail vendor; status active atau suspended. Mengubah atau menghapus commission_percent juga memerlukan commissions.override; nilai yang tidak berubah hanya memerlukan vendors.write. Memulihkan vendor yang diarsipkan juga memerlukan reconciliation.write. Perubahan keuangan konsol memerlukan autentikasi ulang akun. Alokasi yang ada mempertahankan komisi dan tujuan aslinya.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | vendors.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan vendors.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTArsipkan vendor/v1/marketplace/vendors/{vendor_id}/archiveBaca + tulis
Arsipkan hanya setelah kewajiban belum dibayar dan faktur terbuka diselesaikan; jika tidak, mengembalikan 409 vendor_has_obligations. Riwayat dipertahankan. Gunakan status suspended untuk sementara, atau pulihkan vendor lama yang diarsipkan dengan rute pembaruan dan reconciliation.write.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | vendors.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan vendors.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETTujuan vendor/v1/marketplace/vendors/{vendor_id}/destinationsHanya baca
Tujuan berversi dan status pending/approved/disabled. Persetujuan tidak membuktikan kepemilikan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTTambahkan tujuan pembayaran/v1/marketplace/vendors/{vendor_id}/destinationsBaca + tulis
Daftarkan alamat BTC mainnet atau EVM yang didukung yang valid, menunggu persetujuan. Alamat milik proyek, jaringan salah, dan alamat EVM nol ditolak.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | destinations.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan destinations.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTSetujui tujuan/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/approveBaca + tulis
Verifikasi kepemilikan secara independen terlebih dahulu. Nonaktifkan tujuan disetujui yang sudah ada pada vendor/jaringan ini terlebih dahulu; snapshot lama tidak dialihkan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | destinations.approve |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan destinations.approve. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTNonaktifkan tujuan/v1/marketplace/vendors/{vendor_id}/destinations/{destination_id}/disableBaca + tulis
Hentikan pekerjaan baru/belum dikirim yang menggunakan versi ini. Transaksi yang ditandatangani tidak bisa dicabut.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | destinations.approve |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan destinations.approve. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETSaldo vendor/v1/marketplace/vendors/{vendor_id}/balancesHanya baca
Jumlah buku besar tersimpan yang presisi, dikelompokkan berdasarkan identitas aset dan jenis akun yang tidak dapat diubah; bukan saldo dompet langsung yang bisa dibelanjakan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETFaktur Marketplace/v1/marketplace/invoicesHanya baca
Faktur berhalaman; q mencari pesanan, email, deskripsi, metadata, dan UUID faktur. Filter store_id, vendor_id, dan status Marketplace. Faktur biasa dikecualikan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTBuat faktur multivendor/v1/marketplace/invoicesBaca + tulis
Gunakan kembali kolom InvoiceCreateInput normal, ditambah store_id dan allocations. Setiap vendor muncul satu kali, 1–100 bagian positif, total sama persis dengan amount. commission_percent opsional pada faktur/per alokasi memerlukan commissions.override dan autentikasi ulang konsol untuk permintaan sesi. Mengembalikan data.invoice_id dan links.checkout. Tidak adanya metode bersama yang kompatibel mengembalikan kesalahan terperinci; tidak beralih ke aset yang tidak kompatibel.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | invoices.write |
Permintaan
: "${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))Body permintaan
amountstringwajibString desimal biasa tanpa tanda; tanpa tanda positif/negatif atau eksponen, hingga 48 digit bilangan bulat dan 30 angka desimal. Harus positif secara bawaan. Toko bisa mengizinkan faktur bernilai nol di Toko → Faktur; total nol diselesaikan tanpa menerima dana, mengalokasikan alamat, atau biaya pemrosesan.Detail
String desimal biasa tanpa tanda; tanpa tanda positif/negatif atau eksponen, hingga 48 digit bilangan bulat dan 30 angka desimal. Harus positif secara bawaan. Toko bisa mengizinkan faktur bernilai nol di Toko → Faktur; total nol diselesaikan tanpa menerima dana, mengalokasikan alamat, atau biaya pemrosesan.
currencystring | nullopsionalMata uang fiat tiga huruf yang didukung, dinormalisasi menjadi huruf besar. Tidak disertakan atau null mewarisi mata uang faktur toko. Pembuatan juga memerlukan kurs konversi penagihan yang tersedia secara independen.Detail
Mata uang fiat tiga huruf yang didukung, dinormalisasi menjadi huruf besar. Tidak disertakan atau null mewarisi mata uang faktur toko. Pembuatan juga memerlukan kurs konversi penagihan yang tersedia secara independen.
payment_methods[]object[] | nullopsional
Pilih metode yang diaktifkan toko untuk faktur ini. Merchant 5.4.0+: abaikan pilihan tidak dikenal/nonaktif/tidak diterima; jika tidak ada yang cocok, gunakan pengaturan bawaan toko. Tidak disertakan/null juga menggunakan pengaturan bawaan toko; [] tidak valid. Tidak pernah mengaktifkan metode atau mengubah pengaturan toko. Lihat skema pilihan di bawah.Detail
Pilih metode yang diaktifkan toko untuk faktur ini. Merchant 5.4.0+: abaikan pilihan tidak dikenal/nonaktif/tidak diterima; jika tidak ada yang cocok, gunakan pengaturan bawaan toko. Tidak disertakan/null juga menggunakan pengaturan bawaan toko; [] tidak valid. Tidak pernah mengaktifkan metode atau mengubah pengaturan toko. Lihat skema pilihan di bawah.
chain_slugstringwajibSalin chain_slug di Proyek → Toko → Metode pembayaran, atau baca dari GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, seperti ethereum, base, atau bitcoin. Pasangan blockchain/jalur hanya boleh muncul satu kali.Detail
Salin chain_slug di Proyek → Toko → Metode pembayaran, atau baca dari GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, seperti ethereum, base, atau bitcoin. Pasangan blockchain/jalur hanya boleh muncul satu kali.
asset_ids[]UUID[] | nullopsionalUUID asset.id on-chain, bukan alamat kontrak atau ID metode pembayaran faktur. Gunakan ini ATAU asset_tickers. Jangan sertakan kedua pemilih untuk semua aset aktif yang diterima pada blockchain ini. [] dan ID duplikat/nil tidak valid. Pada 5.4.0+, abaikan ID yang tidak aktif/diterima pada blockchain ini di toko ini; pilihan yang sepenuhnya tidak cocok menggunakan pengaturan bawaan toko.Detail
UUID asset.id on-chain, bukan alamat kontrak atau ID metode pembayaran faktur. Gunakan ini ATAU asset_tickers. Jangan sertakan kedua pemilih untuk semua aset aktif yang diterima pada blockchain ini. [] dan ID duplikat/nil tidak valid. Pada 5.4.0+, abaikan ID yang tidak aktif/diterima pada blockchain ini di toko ini; pilihan yang sepenuhnya tidak cocok menggunakan pengaturan bawaan toko.
asset_tickers[]string[] | nullopsionalMerchant 5.3.0+. Simbol seperti BTC, USDC, atau PEPE, dibatasi pada chain_slug dan toko ini. 1–64 ticker unik; spasi tepi dipangkas/tidak peka huruf besar-kecil, 1–40 huruf ASCII/angka/titik/garis bawah/tanda hubung. Gunakan ini ATAU asset_ids. Pada 5.4.0+, abaikan ticker tidak dikenal/nonaktif/tidak diterima. Simbol diterima yang ambigu tetap gagal: gunakan asset_ids. Metode aktif yang dipilih memerlukan dompet dan harga valid; gangguan pemindai on-chain sementara tidak memblokir pembuatan mulai 6.0.6. Lightning secara opsional hanya menerima BTC.Detail
Merchant 5.3.0+. Simbol seperti BTC, USDC, atau PEPE, dibatasi pada chain_slug dan toko ini. 1–64 ticker unik; spasi tepi dipangkas/tidak peka huruf besar-kecil, 1–40 huruf ASCII/angka/titik/garis bawah/tanda hubung. Gunakan ini ATAU asset_ids. Pada 5.4.0+, abaikan ticker tidak dikenal/nonaktif/tidak diterima. Simbol diterima yang ambigu tetap gagal: gunakan asset_ids. Metode aktif yang dipilih memerlukan dompet dan harga valid; gangguan pemindai on-chain sementara tidak memblokir pembuatan mulai 6.0.6. Lightning secara opsional hanya menerima BTC.
payment_railonchain | lightningopsionalBawaan onchain. Untuk memilih Bitcoin Lightning, gunakan {chain_slug: bitcoin, payment_rail: lightning} tanpa asset_ids; asset_tickers secara opsional boleh [BTC]. Bitcoin on-chain tidak mencakup Lightning. Koneksi Lightning toko harus sudah aktif dan siap.Detail
Bawaan onchain. Untuk memilih Bitcoin Lightning, gunakan {chain_slug: bitcoin, payment_rail: lightning} tanpa asset_ids; asset_tickers secara opsional boleh [BTC]. Bitcoin on-chain tidak mencakup Lightning. Koneksi Lightning toko harus sudah aktif dan siap.
order_idstring | nullopsionalReferensi pesanan merchant, 1–128 karakter setelah pemangkasan spasi; karakter kontrol ditolak.
emailstring | nullopsionalEmail pelanggan khusus merchant, dinormalisasi ke alamat ASCII praktis dengan paling banyak 254 karakter. Tidak disertakan atau null tidak menyimpan email.
descriptionstring | nullopsionalDeskripsi yang ditampilkan kepada pelanggan, 1–500 karakter; baris baru dan tab diizinkan.
expires_in_secondsinteger | nullopsionalMasa kuotasi faktur dari 300 sampai 86,400 detik; tidak disertakan atau null mewarisi kebijakan toko.
exchange_rate_spread_percentdecimal string | nullopsionalMarkup kuotasi dari 0 sampai 100, dengan paling banyak dua angka desimal. Tidak disertakan atau null mewarisi pengaturan bawaan toko; "0" menonaktifkannya untuk faktur ini. Diterapkan sebelum pembulatan ke atas, lalu dikunci. Tidak mengubah jumlah fiat faktur atau dasar biaya pemrosesan.Detail
Markup kuotasi dari 0 sampai 100, dengan paling banyak dua angka desimal. Tidak disertakan atau null mewarisi pengaturan bawaan toko; "0" menonaktifkannya untuk faktur ini. Diterapkan sebelum pembulatan ke atas, lalu dikunci. Tidak mengubah jumlah fiat faktur atau dasar biaya pemrosesan.
underpayment_tolerance_percentdecimal string | nullopsionalKekurangan yang diterima dari 0 sampai 99.99 dengan paling banyak dua angka desimal. Tidak disertakan atau null mewarisi pengaturan bawaan toko.
ipn_urlstring | nullopsionalCallback HTTPS publik, paling banyak 2,048 byte dan tanpa kredensial atau fragmen. Menggantikan pengaturan bawaan toko; null/tidak disertakan mewarisinya.
redirect_urlstring | nullopsionalURL sukses HTTPS yang digunakan setelah penyelesaian, paling banyak 2,048 byte dan tanpa kredensial tersemat. Tidak disertakan atau null mewarisi pengaturan bawaan toko dan tidak bisa menghapusnya.
cancel_urlstring | nullopsionalURL kembali HTTPS yang digunakan saat checkout berakhir tanpa pembayaran berhasil. Tidak disertakan atau null mewarisi pengaturan bawaan toko dan tidak bisa menghapusnya.
redirect_automaticallyboolean | nullopsionalTidak disertakan atau null mewarisi kebijakan toko. true memerlukan redirect_url efektif.
languagestring | nullopsionalBahasa pelanggan: en, de, es, pt-BR, it, ru, zh-CN, fr, ko, atau ja. pt berarti Portugis Brasil dan zh berarti Mandarin Sederhana. Tag regional yang didukung seperti de-DE dinormalisasi ke bahasa yang tercantum. Tidak disertakan atau null mewarisi bahasa toko. Bahasa konsol terpisah.Detail
Bahasa pelanggan: en, de, es, pt-BR, it, ru, zh-CN, fr, ko, atau ja. pt berarti Portugis Brasil dan zh berarti Mandarin Sederhana. Tag regional yang didukung seperti de-DE dinormalisasi ke bahasa yang tercantum. Tidak disertakan atau null mewarisi bahasa toko. Bahasa konsol terpisah.
checkout_appearanceobject | nullopsional
Pengaturan tampilan parsial untuk faktur ini. Tidak disertakan/null mengikuti desain toko saat ini. Objek, termasuk {}, membekukan desain dan gambar yang telah ditentukan saat pembuatan. Lihat skema pengesampingan di bawah; tanpa pengaturan keuangan, HTML, CSS, JavaScript, atau URL gambar jarak jauh.Detail
Pengaturan tampilan parsial untuk faktur ini. Tidak disertakan/null mengikuti desain toko saat ini. Objek, termasuk {}, membekukan desain dan gambar yang telah ditentukan saat pembuatan. Lihat skema pengesampingan di bawah; tanpa pengaturan keuangan, HTML, CSS, JavaScript, atau URL gambar jarak jauh.
inherit_default_storebooleanopsionaltrue memilih desain toko bawaan proyek sebagai dasar; jika tidak, gunakan desain efektif toko tujuan. Pengesampingan lalu diterapkan dan disimpan secara independen; nilai flag faktur hasilnya false.Detail
true memilih desain toko bawaan proyek sebagai dasar; jika tidak, gunakan desain efektif toko tujuan. Pengesampingan lalu diterapkan dan disimpan secara independen; nilai flag faktur hasilnya false.
introstringopsionalTeks biasa, masing-masing hingga 2,000 karakter. Intro muncul di atas, Outro di bawah pada setiap status. Baris baru dipertahankan; URL teks yang aman menjadi tautan. String kosong menghapus. customer_message lama diterima sebagai alias intro; jangan kirim keduanya.Detail
Teks biasa, masing-masing hingga 2,000 karakter. Intro muncul di atas, Outro di bawah pada setiap status. Baris baru dipertahankan; URL teks yang aman menjadi tautan. String kosong menghapus. customer_message lama diterima sebagai alias intro; jangan kirim keduanya.
outrostringopsionalTeks biasa, masing-masing hingga 2,000 karakter. Intro muncul di atas, Outro di bawah pada setiap status. Baris baru dipertahankan; URL teks yang aman menjadi tautan. String kosong menghapus. customer_message lama diterima sebagai alias intro; jangan kirim keduanya.Detail
Teks biasa, masing-masing hingga 2,000 karakter. Intro muncul di atas, Outro di bawah pada setiap status. Baris baru dipertahankan; URL teks yang aman menjadi tautan. String kosong menghapus. customer_message lama diterima sebagai alias intro; jangan kirim keduanya.
intro_font_sizeintegeropsionalPiksel: 12, 14, 16, 18, 20, atau 24. Bawaan 16 kecuali mewarisi nilai berbeda.
outro_font_sizeintegeropsionalPiksel: 12, 14, 16, 18, 20, atau 24. Bawaan 16 kecuali mewarisi nilai berbeda.
accent_colorstringopsional#RRGGBB. Latar belakang, kartu, dan tombol boleh kosong untuk warna otomatis. Kontras teks otomatis.
background_colorstringopsional#RRGGBB. Latar belakang, kartu, dan tombol boleh kosong untuk warna otomatis. Kontras teks otomatis.
card_colorstringopsional#RRGGBB. Latar belakang, kartu, dan tombol boleh kosong untuk warna otomatis. Kontras teks otomatis.
button_colorstringopsional#RRGGBB. Latar belakang, kartu, dan tombol boleh kosong untuk warna otomatis. Kontras teks otomatis.
imagesobjectopsional
Kunci logo_light, logo_dark, favicon. Kunci yang tidak disertakan mempertahankan gambar dasar; null menghapusnya. Objek {store_id: UUID, kind?: logo_light|logo_dark|favicon} memakai kembali gambar unggahan efektif toko tersebut dalam proyek yang SAMA. kind bawaan mengikuti kunci tujuan. Unggah di Toko → Checkout terlebih dahulu; salin ID API Toko dari Dasar → ID API. Gambar tidak tersedia atau ID lintas proyek mengembalikan 400. URL eksternal atau data gambar tidak diterima.Detail
Kunci logo_light, logo_dark, favicon. Kunci yang tidak disertakan mempertahankan gambar dasar; null menghapusnya. Objek {store_id: UUID, kind?: logo_light|logo_dark|favicon} memakai kembali gambar unggahan efektif toko tersebut dalam proyek yang SAMA. kind bawaan mengikuti kunci tujuan. Unggah di Toko → Checkout terlebih dahulu; salin ID API Toko dari Dasar → ID API. Gambar tidak tersedia atau ID lintas proyek mengembalikan 400. URL eksternal atau data gambar tidak diterima.
show_order_idbooleanopsionalTampilkan detail ID pesanan dan deskripsi teks biasa di bawah judul. details_expanded membuka detail ID pesanan sejak awal. Hanya tampilan, bukan penyamaran data.
show_descriptionbooleanopsionalTampilkan detail ID pesanan dan deskripsi teks biasa di bawah judul. details_expanded membuka detail ID pesanan sejak awal. Hanya tampilan, bukan penyamaran data.
details_expandedbooleanopsionalTampilkan detail ID pesanan dan deskripsi teks biasa di bawah judul. details_expanded membuka detail ID pesanan sejak awal. Hanya tampilan, bukan penyamaran data.
show_project_namebooleanopsionalMerchant 5.6.0+: tampilkan atau sembunyikan setiap nama pada header checkout pelanggan. Keduanya secara bawaan true. Juga tersedia di Toko → Checkout; diwarisi dan disimpan dalam snapshot faktur seperti pengaturan tampilan lain. Hanya tampilan, bukan penyamaran data.Detail
Merchant 5.6.0+: tampilkan atau sembunyikan setiap nama pada header checkout pelanggan. Keduanya secara bawaan true. Juga tersedia di Toko → Checkout; diwarisi dan disimpan dalam snapshot faktur seperti pengaturan tampilan lain. Hanya tampilan, bukan penyamaran data.
show_store_namebooleanopsionalMerchant 5.6.0+: tampilkan atau sembunyikan setiap nama pada header checkout pelanggan. Keduanya secara bawaan true. Juga tersedia di Toko → Checkout; diwarisi dan disimpan dalam snapshot faktur seperti pengaturan tampilan lain. Hanya tampilan, bukan penyamaran data.Detail
Merchant 5.6.0+: tampilkan atau sembunyikan setiap nama pada header checkout pelanggan. Keduanya secara bawaan true. Juga tersedia di Toko → Checkout; diwarisi dan disimpan dalam snapshot faktur seperti pengaturan tampilan lain. Hanya tampilan, bukan penyamaran data.
featured_chains[]string[]opsionalSlug blockchain berurutan, paling banyak 60 nilai unik (huruf kecil, angka, tanda hubung; hingga 64 karakter). [] menghapus. Hanya metode faktur yang tersedia yang diurutkan ulang.Detail
Slug blockchain berurutan, paling banyak 60 nilai unik (huruf kecil, angka, tanda hubung; hingga 64 karakter). [] menghapus. Hanya metode faktur yang tersedia yang diurutkan ulang.
featured_asset_ids[]UUID[]opsionalHingga 100 ID aset unik berurutan; [] menghapus. Aset bawaan boleh null. ID berasal dari payment-assets, bukan ID intent pembayaran. Ini tidak pernah mengaktifkan metode; pembayaran yang diterima dan preferensi pelanggan yang valid diprioritaskan.Detail
Hingga 100 ID aset unik berurutan; [] menghapus. Aset bawaan boleh null. ID berasal dari payment-assets, bukan ID intent pembayaran. Ini tidak pernah mengaktifkan metode; pembayaran yang diterima dan preferensi pelanggan yang valid diprioritaskan.
default_asset_idUUID|nullopsionalHingga 100 ID aset unik berurutan; [] menghapus. Aset bawaan boleh null. ID berasal dari payment-assets, bukan ID intent pembayaran. Ini tidak pernah mengaktifkan metode; pembayaran yang diterima dan preferensi pelanggan yang valid diprioritaskan.Detail
Hingga 100 ID aset unik berurutan; [] menghapus. Aset bawaan boleh null. ID berasal dari payment-assets, bukan ID intent pembayaran. Ini tidak pernah mengaktifkan metode; pembayaran yang diterima dan preferensi pelanggan yang valid diprioritaskan.
messagesobjectopsional
Objek bahasa dengan kunci en, de, es, pt-BR, it, ru, zh-CN, fr, ko, atau ja, dengan string biasa waiting, confirming, paid, underpaid, expired (masing-masing 500 karakter). Hanya bahasa/status yang diberikan yang berubah; {} menghapus semua pesan, {en:{}} menghapus bahasa Inggris, dan string status kosong menghapus status tersebut. Bahasa Inggris menjadi cadangan. Tidak mengganti status sebenarnya.Detail
Objek bahasa dengan kunci en, de, es, pt-BR, it, ru, zh-CN, fr, ko, atau ja, dengan string biasa waiting, confirming, paid, underpaid, expired (masing-masing 500 karakter). Hanya bahasa/status yang diberikan yang berubah; {} menghapus semua pesan, {en:{}} menghapus bahasa Inggris, dan string status kosong menghapus status tersebut. Bahasa Inggris menjadi cadangan. Tidak mengganti status sebenarnya.
enobjectopsional
deobjectopsional
esobjectopsional
pt-BRobjectopsional
itobjectopsional
ruobjectopsional
zh-CNobjectopsional
frobjectopsional
koobjectopsional
support_urlstringopsionalURL HTTPS hingga 2,048 karakter, tanpa kredensial. Kosong menghapus. Tautan terbuka di jendela baru.
terms_urlstringopsionalURL HTTPS hingga 2,048 karakter, tanpa kredensial. Kosong menghapus. Tautan terbuka di jendela baru.
privacy_urlstringopsionalURL HTTPS hingga 2,048 karakter, tanpa kredensial. Kosong menghapus. Tautan terbuka di jendela baru.
return_button_textstringopsionalLabel hingga 60 karakter. Gunakan redirect_url/cancel_url/redirect_automatically/language tingkat atas untuk perilaku faktur.
show_return_buttonbooleanopsionalTampilkan tombol manual Kembali ke merchant/batal di checkout, termasuk status akhir. Jangan sertakan untuk mewarisi tampilan toko (bawaan true); false menyembunyikannya. Tidak membatalkan faktur, menyembunyikan URL dalam JSON, atau menonaktifkan pengalihan sukses otomatis. Tetapkan redirect_automatically tingkat atas ke false secara terpisah jika diperlukan. Memerlukan merchant 8.1.4 atau yang lebih baru.Detail
Tampilkan tombol manual Kembali ke merchant/batal di checkout, termasuk status akhir. Jangan sertakan untuk mewarisi tampilan toko (bawaan true); false menyembunyikannya. Tidak membatalkan faktur, menyembunyikan URL dalam JSON, atau menonaktifkan pengalihan sukses otomatis. Tetapkan redirect_automatically tingkat atas ke false secara terpisah jika diperlukan. Memerlukan merchant 8.1.4 atau yang lebih baru.
metadataobject | nullopsional
Objek JSON khusus merchant; tidak disertakan atau null menjadi {}, maksimum 4,096 byte terenkode dan lima tingkat penyarangan. firstname, lastname, street, street2, zip, city, country, countryiso2, company, dan vatid divalidasi, dinormalisasi, dan diproyeksikan ke kolom ringkasan pelanggan.Detail
Objek JSON khusus merchant; tidak disertakan atau null menjadi {}, maksimum 4,096 byte terenkode dan lima tingkat penyarangan. firstname, lastname, street, street2, zip, city, country, countryiso2, company, dan vatid divalidasi, dinormalisasi, dan diproyeksikan ke kolom ringkasan pelanggan.
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"}]Detail
[{"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"}]
Respons 200 application/json
Contoh respons
{
"data": {
"invoice_id": "YOUR_INVOICE_ID",
"status": "new",
"marketplace": {
"state": "pending",
"allocations": []
}
},
"links": {
"checkout": "https://pay.example.com/invoice/YOUR_INVOICE_ID"
}
}Kolom respons
Catatan penggunaan
- Memerlukan invoices.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETFaktur dan alokasi/v1/marketplace/invoices/{invoice_id}Hanya baca
Detail faktur normal ditambah status marketplace, revision, hold_reason, alokasi beku, snapshot kebijakan, 200 pembayaran terbaru, dan 100 pembayaran vendor terkait terbaru dengan penanda pemotongan. Checkout publik tidak menampilkan data vendor.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETBukti pembayaran faktur/v1/marketplace/invoices/{invoice_id}/paymentsHanya baca
Bukti pembayaran normal dengan page/per_page. Observasi bukan pembayaran vendor.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETAlokasi faktur/v1/marketplace/invoices/{invoice_id}/allocationsHanya baca
Snapshot bagian/komisi/tujuan yang tidak dapat diubah serta nilai atomik kotor, komisi, dan bersih yang presisi setelah penyelesaian memenuhi syarat.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTBatalkan faktur belum dibayar/v1/marketplace/invoices/{invoice_id}/cancelBaca + tulis
Hanya faktur new atau expired yang belum dibayar. Penerimaan terlambat ditahan untuk ditinjau. Revisi adalah revisi faktur Marketplace.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | invoices.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan invoices.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTTahan alokasi/v1/marketplace/invoices/{invoice_id}/allocations/holdBaca + tulis
Tahan alokasi yang belum ditandatangani tanpa menghapus kewajiban. Pembayaran yang ditandatangani atau belum pasti tetap dilacak.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | reconciliation.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan reconciliation.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTTinjau dan lepaskan alokasi/v1/marketplace/invoices/{invoice_id}/allocations/releaseBaca + tulis
Periksa ulang kecukupan dana/finalitas. approved_amount_atomic opsional secara eksplisit menerima pembagian lebih kecil yang sepenuhnya didukung dana sebelum pembekuan alokasi; tidak pernah merekayasa dana penerimaan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | reconciliation.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan reconciliation.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTTautkan ulang tujuan yang belum dibayar/v1/marketplace/invoices/{invoice_id}/allocations/{allocation_id}/destinationBaca + tulis
Revisi alokasi wajib. Hanya pekerjaan yang belum dicadangkan/ditandatangani dan versi yang disetujui terpisah untuk vendor yang sama pada jaringan asli. Diaudit; pekerjaan bertanda tangan tidak bisa berubah.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | reconciliation.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan reconciliation.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTSiapkan pengembalian dana penuh/v1/marketplace/invoices/{invoice_id}/refundBaca + tulis
Siapkan pengembalian penuh jumlah yang diterima dalam aset yang sama, yang disetujui secara terpisah. Sebelum pembayaran vendor, cadangkan dana yang belum dibayar dan balikkan komisi saat konfirmasi. Setelah semua vendor dibayar, gunakan dana bebas terpisah dari alamat utama. Jangan pernah menyimpulkan alamat pengembalian dana pelanggan dari pengirim.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | reconciliation.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan reconciliation.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETTemukan alokasi pembayaran/v1/marketplace/allocationsHanya baca
Kandidat berhalaman; filter status (available dan lainnya), asset_id, vendor_id, store_id, dan q (vendor/pesanan/faktur).
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETSaldo buku besar proyek/v1/marketplace/balancesHanya baca
Total aset/akun terkelompok yang presisi, termasuk yang ditahan, tersedia, dicadangkan, dibayar, komisi, pengembalian dana, dan biaya jaringan. Akun penyeimbang eksternal dikecualikan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETJurnal yang tidak dapat diubah/v1/marketplace/ledgerHanya baca
Pergerakan berhalaman yang hanya dapat ditambahi; filter q referensi/akun, asset_id, dan vendor_id. Jumlah menggunakan string atomik; tidak ada entri yang bisa diedit atau ditandai lunas secara manual.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETRiwayat pembayaran/v1/marketplace/payoutsHanya baca
Induk berhalaman; filter state, asset_id, vendor_id, atau q ID/simbol. Paid berarti konfirmasi independen, bukan sekadar penyiaran.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTPratinjau rencana alokasi/v1/marketplace/payouts/previewBaca + tulis
Rencana akuntansi hanya baca, tanpa pencadangan dana atau wewenang pembelanjaan. Biaya maksimum adalah batas pengguna, bukan perkiraan biaya sebenarnya. Penyiapan melakukan pemeriksaan langsung kemudian.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | payouts.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan payouts.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTSiapkan pembayaran/v1/marketplace/payoutsBaca + tulis
Cadangkan 1–100 ID alokasi tersedia dalam satu aset/dompet. BTC memerlukan semua bagian yang belum dibayar untuk setiap faktur terpilih dalam satu batch multi-output. Anggaran berupa string atomik dalam aset biaya native. Membuat rencana awaiting_approval, tidak menyiarkan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | payouts.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"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": []
}
}Kolom respons
Catatan penggunaan
- Memerlukan payouts.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETDetail pembayaran/v1/marketplace/payouts/{payout_id}Hanya baca
Rencana/hash yang tidak dapat diubah, revisi, kedaluwarsa, item penerima, percobaan turunan yang dipertahankan, progres, biaya presisi, dan tautan penjelajah. Tidak pernah kunci privat atau byte bertanda tangan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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": []
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTSetujui dan kirim/v1/marketplace/payouts/{payout_id}/approveBaca + tulis
Otorisasi secara eksplisit rencana tersimpan yang persis dalam masa berlakunya. Antrekan pendanaan gas terbatas dan transaksi vendor di latar belakang.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | payouts.approve |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan payouts.approve. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTTinjau dan lanjutkan pembayaran/v1/marketplace/payouts/{payout_id}/resumeBaca + tulis
Hanya needs_attention. Gunakan kembali rencana/hash tersimpan; penerima terkonfirmasi tidak pernah dikirim ulang. Dua penyedia independen harus membuktikan revert EVM kanonis dengan konfirmasi cukup sebelum transaksi turunan gagal bisa diganti. Biaya sebelumnya tetap memakai anggaran yang disetujui dan semua hash tetap dalam riwayat. Pengiriman token tidak diketahui/parsial mengembalikan payout_recovery_unverified; dana yang dicadangkan tetap ditahan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | payouts.approve |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan payouts.approve. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTBatalkan pekerjaan yang belum ditandatangani/v1/marketplace/payouts/{payout_id}/cancelBaca + tulis
Lepaskan hanya pencadangan dana yang aman karena belum ditandatangani/diajukan. Penerima terkonfirmasi dan audit tetap ada. Pekerjaan bertanda tangan/belum pasti tidak bisa dibatalkan. Revert terbukti yang secara eksplisit dipulihkan tidak lagi memblokir pembatalan sisa pekerjaan yang belum ditandatangani.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | payouts.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan payouts.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETKebijakan pembayaran otomatis/v1/marketplace/policiesHanya baca
Baca kebijakan per aset, revision, next_attempt_at, last_checked_at, dan last_error aman saat penyiapan atau otorisasi perlu perhatian.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": []
}Kolom respons
data[]arrayCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTOtorisasi kebijakan pembayaran/v1/marketplace/policiesBaca + tulis
String atomik presisi; minimum <= transfer <= pokok harian, batas biaya/gas <= anggaran harian masing-masing. interval_seconds 60–604800; minimum_confirmations 1–100000 tunduk pada batas minimum blockchain. Revision 0 membuat. Kebijakan aktif bisa mengirim tanpa klik tambahan; pertahankan false sampai ditinjau.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | policies.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan policies.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETWebhook Marketplace/v1/marketplace/webhooksHanya baca
Hingga 20 endpoint ditambah event_types yang didukung. Tidak pernah mengembalikan rahasia penandatanganan terenkripsi atau teks biasa.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
]
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTBuat webhook Marketplace/v1/marketplace/webhooksBaca + tulis
Hanya HTTPS publik, tanpa kredensial, tujuan privat, atau pengalihan. Mengembalikan signing_secret satu kali per respons pembuatan idempoten tersimpan; simpan dengan aman. Terpisah dari rahasia IPN toko.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | webhooks.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan webhooks.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTPerbarui webhook Marketplace/v1/marketplace/webhooks/{webhook_id}/updateBaca + tulis
Perubahan membatalkan pengiriman lama yang belum dikirim. Rahasia tetap sama; payload lama yang tidak dapat diubah tidak pernah dialihkan ke URL baru.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | webhooks.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan webhooks.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTNonaktifkan webhook Marketplace/v1/marketplace/webhooks/{webhook_id}/disableBaca + tulis
Hentikan pengiriman baru; riwayat peristiwa tersimpan tetap ada.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | webhooks.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan webhooks.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETPeristiwa Marketplace/v1/marketplace/eventsHanya baca
Referensi peristiwa berhalaman yang tidak dapat diubah. q mencari tipe/referensi; status memfilter event_type.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETBaca peristiwa tersimpan/v1/marketplace/events/{event_id}Hanya baca
Mengembalikan payload peristiwa asli yang tidak dapat diubah, bukan rekonstruksi dari saldo terkini.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}
]
}
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETRiwayat pengiriman Marketplace/v1/marketplace/webhook-deliveriesHanya baca
Pengiriman berhalaman, jenis peristiwa, percobaan, dan hasil terakhir. Filter status pending/sending/succeeded/failed/cancelled; q jenis peristiwa.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": [],
"pagination": {
"page": 1,
"per_page": 25,
"total": 0,
"pages": 1
}
}Kolom respons
Catatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETDetail pengiriman/v1/marketplace/webhook-deliveries/{delivery_id}Hanya baca
URL asli, payload tersimpan, hasil HTTP, dan kesalahan aman; tanpa rahasia penandatanganan.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | marketplace.read |
Parameter kueri
pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
per_pageopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
qopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
statusopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
store_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
vendor_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
asset_idopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
fromopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
toopsionalGunakan hanya filter yang didokumentasikan untuk resource ini. Daftar berhalaman secara bawaan berisi 25 dan mengizinkan hingga 100 baris.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan marketplace.read. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
POSTKirim ulang peristiwa yang sama/v1/marketplace/webhook-deliveries/{delivery_id}/resendBaca + tulis
Hanya pengiriman selesai dan endpoint aktif yang tidak berubah; hingga 20 percobaan ulang manual. Menggunakan kembali event_id. Notifikasi gagal tidak pernah mengotorisasi pembayaran kedua.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MARKETPLACE_API_TOKEN |
| Idempotency-Key | wajib | 16–128 huruf, angka, -, _, atau .; simpan secara persisten bersama permintaan persis ini |
| Parameter | Tipe / lokasi | Aturan |
|---|---|---|
| permission | credential scope | webhooks.write |
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"data": {}
}Kolom respons
dataobjectCatatan penggunaan
- Memerlukan webhooks.write. Contoh respons menampilkan kolom yang dipilih; GET resource untuk bukti tersimpan lengkap.
- Setiap POST memerlukan Idempotency-Key 16–128 karakter yang disimpan secara persisten (huruf, angka, -, _, atau .). Gunakan kembali kunci dan instruksi JSON yang sama setelah batas waktu terlampaui. Instruksi berbeda mengembalikan 409. Respons selesai disimpan selama 30 hari; kunci lama menjadi penanda yang tidak bisa digunakan ulang. Jangan pernah mengganti kunci hanya untuk melewati hasil yang belum pasti.
- Kunci memiliki daftar proyek, pembatasan toko faktur opsional, kedaluwarsa, daftar izin IP, dan kuota 1–600/menit (bawaan 60). HTTP 429 menyertakan Retry-After. Kunci yang dibatasi ke toko tidak bisa melihat vendor, saldo proyek, buku besar, pembayaran, atau pengaturan. Simpan kredensial pembelanjaan hanya di server tepercaya, jangan pernah di browser atau aplikasi seluler yang didistribusikan.
Kesalahan
GETDaftar pengecualian pembayaran/v1/projects/{project_id}/reconciliationHanya baca
Satu antrean tinjauan berhalaman untuk pembayaran kurang bayar, lebih bayar, terlambat, terkena reorg, atau ambigu, pengiriman gagal, serta metode nonaktif/kedaluwarsa. Kasus yang diakui operator dibuka kembali saat bukti baru tiba.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
Parameter path
Parameter kueri
reasonstringunderpaid, overpaid, late, reorged, ambiguous, delivery_failed, disabled_method, atau expired_method.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{"data":[],"pagination":{"page":1,"per_page":25,"total":0,"has_more":false},"counts":{"open":0,"resolved":0}}Kolom respons
data[]object[]selalu
Kasus yang paling baru diperbarui lebih dahulu. Gunakan invoice_id, bukan id internal, dalam URL detail merchant.
idUUIDselaluID catatan internal / UUID faktur yang ditampilkan kepada pelanggan. invoice_id cocok dengan payload callback.
invoice_idUUIDselaluID catatan internal / UUID faktur yang ditampilkan kepada pelanggan. invoice_id cocok dengan payload callback.
paginationobjectselalu
page (1–40001), per_page (25), total baris yang cocok, has_more.
Catatan penggunaan
- Hanya baca, dibatasi ke proyek, dan tercakup dalam kuota kredensial. Keputusan keuangan dan pengembalian dana tetap hanya melalui konsol.
- Baris berisi id (UUID internal), invoice_id (UUID publik, sama dengan callback), informasi toko, jumlah/mata uang fiat asli, invoice_status, status kasus, alasan, revisi, dan updated_at. Gunakan invoice_id pada endpoint detail merchant.
- Deteksi otomatis mengikuti jendela pemantauan faktur asli; Pindai ulang memperpanjang observasi satu jam tanpa mengaktifkan checkout. Metode setelah penyelesaian/dibatalkan terus dipantau dalam jendela tersebut.
Kesalahan
GETBaca bukti rekonsiliasi/v1/projects/{project_id}/reconciliation/{invoice_id}Hanya baca
Mengembalikan faktur, kasus, total metode presisi dan jumlah pengembalian dana tersedia, transaksi teramati, riwayat pengiriman, keputusan merchant, serta transfer pengembalian dana tertaut. Tidak pernah menampilkan kunci penandatanganan atau rahasia callback.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
Parameter path
Parameter kueri
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{"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":[]}Kolom respons
invoiceobjectselalu
Faktur merchant lengkap: kolom ringkasan, metadata pribadi, dan payment_intents. Tidak dibungkus dalam data.
emailstring | nullselaluEmail pelanggan khusus merchant. Tidak pernah dikembalikan oleh checkout publik.
customer_namestring | nullselaluNama tampilan yang diturunkan dari metadata pribadi firstname, lastname, dan company.
customer_addressstring | nullselaluAlamat satu baris untuk merchant yang diturunkan dari metadata pribadi company, street, street2, zip, city, country, countryiso2, dan vatid.
exchange_rate_spread_percentdecimal stringselaluSpread kuotasi terkunci: pengesampingan saat pembuatan, atau pengaturan bawaan toko jika tidak disertakan. Diterapkan sebelum pembulatan ke atas; tidak pernah berubah pada faktur ini.
underpayment_tolerance_percentdecimal stringselaluPersentase kekurangan yang diterima dan tidak dapat diubah, disimpan dalam snapshot saat faktur dibuat.
amount_statusamount statusselalunone, partial, paid, atau overpaid. Faktur bernilai nol yang secara eksplisit diizinkan diselesaikan dengan none dan tanpa metode pembayaran.
winning_payment_intent_idUUID | nullselaluMetode pembayaran yang menyelesaikan faktur, saat dipilih.
monitoring_expires_atRFC 3339 timestampselaluBatas akhir pemantauan terlambat paling akhir yang dikonfigurasi di antara metode pembayaran.
ipn_urlstring | nullselaluTujuan IPN efektif per faktur. Hanya respons merchant; dihilangkan dari checkout publik.
cancel_urlstring | nullselaluURL kembali efektif yang digunakan saat checkout berakhir tanpa pembayaran berhasil.
redirect_automaticallybooleanselaluApakah checkout harus mengalihkan secara otomatis setelah berhasil.
metadataobjectselaluMetadata merchant. Tidak pernah dikembalikan oleh checkout publik. Alat pembayaran konsol menambahkan asal payment_tool (id, kind, title, pricing, requested_amount, request_id); ini tidak membuktikan pembayaran. Autentikasi callback dan penuhi invoice.settled satu kali per invoice_id.Detail
Metadata merchant. Tidak pernah dikembalikan oleh checkout publik. Alat pembayaran konsol menambahkan asal payment_tool (id, kind, title, pricing, requested_amount, request_id); ini tidak membuktikan pembayaran. Autentikasi callback dan penuhi invoice.settled satu kali per invoice_id.
payment_intents[]object[]selalu
Metode pembayaran yang diberi kuotasi dan status pemantauan.
payment_railonchain | lightningselaluTransport faktur. Bitcoin on-chain dan Lightning bisa berbagi asset_id; gunakan id intent beserta kolom ini, bukan simbol saja. Ini berbeda dari payment_rail pemindai dalam katalog aset.Detail
Transport faktur. Bitcoin on-chain dan Lightning bisa berbagi asset_id; gunakan id intent beserta kolom ini, bukan simbol saja. Ini berbeda dari payment_rail pemindai dalam katalog aset.
bolt11string | nullselaluPermintaan pembayaran Lightning, jika tidak null. Bayar permintaan ini dengan dompet Lightning; jangan pernah mengirim dana on-chain ke hash pembayarannya.
networkstringselaluJaringan yang dikonfigurasi, saat ini mainnet untuk aset pembayaran yang didukung.
asset_decimalsintegerselaluPresisi unit atomik. BTC Lightning menggunakan 11 (millisatoshi), bukan 8 seperti Bitcoin on-chain. Kuotasi berupa satoshi utuh; penerimaan mempertahankan presisi millisatoshi.
quote_ratedecimal stringselaluUnit aset per satu unit mata uang faktur, termasuk spread terkunci. Contohnya 1.02 USDC per USD. Bukan kurs kebalikannya.
quote_detailsobject | nullselaluAsal kuotasi terkunci: reference_rate sebelum spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at, dan asset_fetched_at. Null pada faktur lama; tidak ada nilai historis yang direkayasa.Detail
Asal kuotasi terkunci: reference_rate sebelum spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at, dan asset_fetched_at. Null pada faktur lama; tidak ada nilai historis yang direkayasa.
expected_amountdecimal stringselaluJumlah aset terkunci yang presisi untuk dibayar setelah spread dan pembulatan ke atas. Mulai 4.1.1, stablecoin fiat terverifikasi yang dikenali (seperti USDC, USDT, DAI, USDS, EURC) dibulatkan ke atas hingga paling banyak dua desimal; 1.321 menjadi 1.33, tidak pernah 1.32. Ini jumlah yang diharapkan bahkan dengan toleransi nol. Aset lain mempertahankan presisi adaptif. Harga faktur yang sudah ada tidak pernah dihitung ulang.Detail
Jumlah aset terkunci yang presisi untuk dibayar setelah spread dan pembulatan ke atas. Mulai 4.1.1, stablecoin fiat terverifikasi yang dikenali (seperti USDC, USDT, DAI, USDS, EURC) dibulatkan ke atas hingga paling banyak dua desimal; 1.321 menjadi 1.33, tidak pernah 1.32. Ini jumlah yang diharapkan bahkan dengan toleransi nol. Aset lain mempertahankan presisi adaptif. Harga faktur yang sudah ada tidak pernah dihitung ulang.
minimum_payment_amountdecimal stringselaluJumlah terkecil yang diterima sebagai lunas setelah menerapkan toleransi faktur.
minimum_payment_amount_atomicinteger stringselaluAmbang diterima yang presisi dalam unit terkecil aset.
destination_addressstringselaluAlamat penerimaan on-chain, atau hash pembayaran 64 karakter untuk Lightning. Gunakan bolt11 untuk membayar Lightning; hash-nya bukan alamat Bitcoin.
destination_tagstring | nullselaluReferensi pembayaran publik wajib jika jalur menggunakannya: destination tag XRP, ID memo Stellar, atau komentar faktur TON. Null untuk jalur dengan alamat unik.
caseobject | nullselalu
Kasus saat ini dengan status, alasan, revisi, dan stempel waktu; null jika tidak ada pengecualian. Bukti internal dikecualikan.
methods[]object[]selaluid, 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, dan spending_supported. Jumlah atomik berupa string.Detail
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, dan spending_supported. Jumlah atomik berupa string.
history[]object[]selalu25 keputusan terbaru untuk halaman ini: id, action, note, actor, result, created_at.
history_paginationobjectselalu
page, per_page (25), total. Hanya riwayat keputusan yang dipaginasi berdasarkan page.
refunds[]object[]selalu100 pengembalian dana terbaru: id, payment_intent_id, amount_atomic, destination, status, request, treasury_intent_id, transfer_status, created_at, dan transactions (id/status). Pengajuan pengembalian dana hanya melalui konsol.Detail
100 pengembalian dana terbaru: id, payment_intent_id, amount_atomic, destination, status, request, treasury_intent_id, transfer_status, created_at, dan transactions (id/status). Pengajuan pengembalian dana hanya melalui konsol.
observations[]object[]selalu100 terbaru: payment_intent_id, transaction_id, event_index, amount, status, confirmations, observed_at, symbol, chain, dan disabled_at_detection. explorer_name/explorer_url disertakan jika didukung.Detail
100 terbaru: payment_intent_id, transaction_id, event_index, amount, status, confirmations, observed_at, symbol, chain, dan disabled_at_detection. explorer_name/explorer_url disertakan jika didukung.
deliveries[]object[]selalu50 terbaru: id, kind, status, attempts, response_status, error, next_attempt_at, event_type, dan created_at. Tanpa rahasia callback.
Catatan penggunaan
- case bernilai null jika faktur belum menghasilkan pengecualian. 100 observasi dan 50 pengiriman terbaru dikembalikan; riwayat keputusan berhalaman.
- refundable_atomic memerlukan setidaknya satu konfirmasi jaringan, mengecualikan pencadangan pengembalian dana yang ada, dan bukan janji dana dompet yang bisa dibelanjakan. Kuotasi langsung juga memvalidasi kesiapan dompet, saldo sumber, dan biaya.
- Pengembalian dana yang disiarkan berarti diajukan ke endpoint blockchain, bukan penerimaan pelanggan yang dikonfirmasi secara independen. Biaya bersifat tambahan dan biaya pemrosesan fiat tidak otomatis dikreditkan dengan menerbitkan pengembalian dana.
- Menu proyek konsol → Perlu perhatian menyediakan batal, terima, tolak, buka ulang, tinjau, catatan, Pindai ulang, percobaan ulang pengiriman, dan pengembalian dana pada blockchain yang didukung. Keputusan menggunakan sesi yang dilindungi CSRF, request_id unik, revisi kasus terkini, catatan wajib, dan konfirmasi eksplisit; token bearer tidak bisa memanggil perubahan tersebut.
Kesalahan
GETPenemuan layanan API/Publik
Respons edge host API yang dikelola yang mengonfirmasi peran API publik v1. Respons ini dihasilkan proxy yang dikelola, bukan router Axum merchant.
Autentikasi & header
Publik
Permintaan
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))Respons 200 application/json
Contoh respons
{
"service": "Wholly Crypto API",
"status": "ready",
"version": "v1"
}Kolom respons
Catatan penggunaan
- Token bearer tidak diperlukan.
- Hanya nama host API yang dikelola yang menjamin respons root persis ini.
Kesalahan
GETKesehatan layanan/healthzPublik
Memeriksa keterjangkauan aplikasi dan ping database dua detik. Gunakan untuk pemantauan, bukan sebagai pengganti status faktur.
Autentikasi & header
Publik
Permintaan
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))Respons 200 healthy; 503 database unavailable
Contoh respons
{
"status": "ok",
"database": "ok",
"version": "0.1.0"
}Kolom respons
Catatan penggunaan
- Token bearer tidak diperlukan.
- Nilai version adalah versi paket yang berjalan, bukan versi path API.
Kesalahan
GETDaftar aset pembayaran proyek/v1/projects/{project_id}/payment-assetsHanya baca
Mencantumkan aset native dan token terverifikasi dengan kebijakan proyek, kesiapan dompet blockchain, serta kemampuan pemindai/saldo terinstal. scanner_ready adalah gerbang build adapter, bukan hasil kuorum endpoint langsung. Mulai 6.0.6, pembuatan mempertahankan metode yang dikonfigurasi saat pemindai tidak aktif. Verifikasi penerimaan tetap memerlukan ambang penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1).
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | direkomendasikan | application/json |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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" }] }
}
]
}Kolom respons
data[]object[]
assetobjectselalu
Aset native atau token terverifikasi yang persisten.
asset_kindnative | tokenselaluApakah penyelesaian menggunakan mata uang blockchain atau kontrak/mint terverifikasi.
payment_railstringselaluJalur runtime: utxo, evm-native, solana-native, account-native, privacy-native, atau token-transfer.
contract_addressstring | nullselaluKontrak ERC-20 kanonis atau mint SPL untuk token; null untuk aset native.
coingecko_idstring | nullselaluIdentitas penemuan/harga. Null untuk kontrak kustom; jangan pernah menyimpulkan harga pasar dari tickernya. Metadata CoinGecko saja tidak pernah membuat token bisa dipilih.
custom_tokenbooleanselaluKontrak kustom terverifikasi on-chain dengan harga USD tetap atau pool DEX terpilih yang berlaku dalam proyek.
token_standarderc20 | spl-token | nullselaluStandar token runtime terverifikasi; null untuk aset native.
metadata_verified_attimestamp | nullselaluWaktu verifikasi metadata on-chain untuk token yang dipromosikan.
payment_supportedbooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
scanner_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
balance_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
default_finality_modeconfirmations | finalizedselaluModel finalitas bawaan yang diwarisi kebijakan proyek baru.
policyobject | nullselalu
Kebijakan aktivasi/finalitas proyek, atau null jika belum dikonfigurasi. Mencakup custom_price_mode (fixed/dex), custom_price_usd (string desimal tetap atau null), custom_dex_pair (pool terpilih atau null), dan custom_dex (dex_id, quote_symbol, price_usd saat ini atau null, liquidity_usd, fetched_at, last_error). Harga kustom dibagi oleh toko dalam proyek ini.Detail
Kebijakan aktivasi/finalitas proyek, atau null jika belum dikonfigurasi. Mencakup custom_price_mode (fixed/dex), custom_price_usd (string desimal tetap atau null), custom_dex_pair (pool terpilih atau null), dan custom_dex (dex_id, quote_symbol, price_usd saat ini atau null, liquidity_usd, fetched_at, last_error). Harga kustom dibagi oleh toko dalam proyek ini.
enabledbooleanwajibMengaktifkan atau menonaktifkan aset untuk proyek. Blockchain native harus diaktifkan sebelum token apa pun.
finality_modeconfirmations | finalizedwajibKebijakan finalitas yang didukung jalur aset. finalized memerlukan required_confirmations=1.
required_confirmationsintegerwajibJalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.Detail
Jalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.
walletobject | nullselalu
Dompet proyek nonkustodial blockchain. Token berbagi dompet native blockchain-nya.
public_keystring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
primary_addressstring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
backup_confirmed_attimestamp | nullselaluBukan null setelah operator mengonfirmasi cadangan pemulihan.
activation_requiredbooleanselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
activation_verified_attimestamp|nullselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
receive_readinessobject | null5.5.0+
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.Detail
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
monero_wallet_rpcMoneroWalletRpcBinding | nullselaluStatus ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.Detail
Status ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.
balances[]object[]selalu
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.Detail
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.
active_store_countintegerselaluJumlah toko aktif yang saat ini memilih aset ini. Ini gambaran penerimaan; pelacakan saldo hanya baca tetap independen.
active_store_ids[]UUID[]selaluToko aktif dalam proyek ini yang saat ini menerima aset. Ini memungkinkan pemfilteran toko lokal yang presisi tanpa permintaan API lain.
tracking_activebooleanselaluApakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.Detail
Apakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.
balancedecimal string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
balance_atomicinteger string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
statuspending | refreshing | fresh | stale | errorselaluStatus pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.Detail
Status pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.
total_value_usddecimal string | nullselaluJumlah saldo sebagai referensi yang memiliki harga USD terkini.
balance_statuspending | refreshing | fresh | stale | error | unknownselaluKebaruan cache gabungan; unknown adalah cadangan defensif dan tidak satu pun status ini membuktikan penyelesaian faktur.
balance_checked_attimestamp | nullselaluPemeriksaan saldo berhasil paling lama yang relevan dan diwakili oleh agregat.
recent_payments[]object[]selalu
Hingga tiga observasi valid terbaru berstatus detected, confirming, atau final yang diatribusikan ke dompet persis ini.
invoice_public_idUUIDselaluIdentitas faktur yang ditampilkan kepada pelanggan yang terkait dengan observasi.
statusdetected | confirming | finalselaluStatus observasi valid saat ini. Observasi reorged, replaced, dan invalid dikecualikan.
wallet_readinessreadiness enumselaluunsupported, 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, atau ready.Detail
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, atau ready.
receive_readinessobject | null5.5.0+
Penilaian penyiapan penerimaan proyek bersama. Mencakup pemeriksaan dompet dan penyedia pemindai independen, terpisah dari kebaruan saldo serta gas pengiriman. Null jika tidak ada kebijakan proyek. Mata uang/kurs faktur diperiksa saat membuat faktur.Detail
Penilaian penyiapan penerimaan proyek bersama. Mencakup pemeriksaan dompet dan penyedia pemindai independen, terpisah dari kebaruan saldo serta gas pengiriman. Null jika tidak ada kebijakan proyek. Mata uang/kurs faktur diperiksa saat membuat faktur.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
Catatan penggunaan
- Token bisa terdaftar secara global tetapi tetap tidak bisa dipilih jika scanner_ready atau payment_supported false.
- Matriks kemampuan operator juga memerlukan peran endpoint pemindai yang persis; endpoint sehat yang melayani API tidak kompatibel tidak dihitung.
- Token berbagi dompet proyek pada blockchain native-nya; tidak membuat frasa seed lain.
- Ringkasan dompet tersemat hanya mencakup kesiapan dan membiarkan saldo kosong; gunakan GET /v1/projects/{project_id}/wallets untuk saldo yang diperkaya.
Kesalahan
PUTPerbarui kebijakan aset proyek/v1/projects/{project_id}/payment-assets/{asset_id}Baca + tulis
Membuat atau mengganti kebijakan proyek untuk satu aset persisten dan mengembalikan daftar aset proyek yang disegarkan. Menonaktifkan blockchain native membuat aset native dan tokennya tidak tersedia untuk faktur baru, tetapi mempertahankan kebijakan token, dompet, dan pilihan toko agar bisa dilanjutkan nanti.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | wajib | application/json |
| Accept | direkomendasikan | application/json |
Parameter path
Permintaan
: "${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))Body permintaan
enabledbooleanwajibMengaktifkan atau menonaktifkan aset untuk proyek. Blockchain native harus diaktifkan sebelum token apa pun.
finality_modeconfirmations | finalizedwajibKebijakan finalitas yang didukung jalur aset. finalized memerlukan required_confirmations=1.
required_confirmationsintegerwajibJalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.Detail
Jalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.
Respons 200 application/json
Contoh respons
{
"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" }
]
}Kolom respons
data[]object[]
assetobjectselalu
Aset native atau token terverifikasi yang persisten.
asset_kindnative | tokenselaluApakah penyelesaian menggunakan mata uang blockchain atau kontrak/mint terverifikasi.
payment_railstringselaluJalur runtime: utxo, evm-native, solana-native, account-native, privacy-native, atau token-transfer.
contract_addressstring | nullselaluKontrak ERC-20 kanonis atau mint SPL untuk token; null untuk aset native.
coingecko_idstring | nullselaluIdentitas penemuan/harga. Null untuk kontrak kustom; jangan pernah menyimpulkan harga pasar dari tickernya. Metadata CoinGecko saja tidak pernah membuat token bisa dipilih.
custom_tokenbooleanselaluKontrak kustom terverifikasi on-chain dengan harga USD tetap atau pool DEX terpilih yang berlaku dalam proyek.
token_standarderc20 | spl-token | nullselaluStandar token runtime terverifikasi; null untuk aset native.
metadata_verified_attimestamp | nullselaluWaktu verifikasi metadata on-chain untuk token yang dipromosikan.
payment_supportedbooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
scanner_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
balance_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
default_finality_modeconfirmations | finalizedselaluModel finalitas bawaan yang diwarisi kebijakan proyek baru.
policyobject | nullselalu
Kebijakan aktivasi/finalitas proyek, atau null jika belum dikonfigurasi. Mencakup custom_price_mode (fixed/dex), custom_price_usd (string desimal tetap atau null), custom_dex_pair (pool terpilih atau null), dan custom_dex (dex_id, quote_symbol, price_usd saat ini atau null, liquidity_usd, fetched_at, last_error). Harga kustom dibagi oleh toko dalam proyek ini.Detail
Kebijakan aktivasi/finalitas proyek, atau null jika belum dikonfigurasi. Mencakup custom_price_mode (fixed/dex), custom_price_usd (string desimal tetap atau null), custom_dex_pair (pool terpilih atau null), dan custom_dex (dex_id, quote_symbol, price_usd saat ini atau null, liquidity_usd, fetched_at, last_error). Harga kustom dibagi oleh toko dalam proyek ini.
enabledbooleanwajibMengaktifkan atau menonaktifkan aset untuk proyek. Blockchain native harus diaktifkan sebelum token apa pun.
finality_modeconfirmations | finalizedwajibKebijakan finalitas yang didukung jalur aset. finalized memerlukan required_confirmations=1.
required_confirmationsintegerwajibJalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.Detail
Jalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.
walletobject | nullselalu
Dompet proyek nonkustodial blockchain. Token berbagi dompet native blockchain-nya.
public_keystring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
primary_addressstring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
backup_confirmed_attimestamp | nullselaluBukan null setelah operator mengonfirmasi cadangan pemulihan.
activation_requiredbooleanselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
activation_verified_attimestamp|nullselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
receive_readinessobject | null5.5.0+
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.Detail
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
monero_wallet_rpcMoneroWalletRpcBinding | nullselaluStatus ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.Detail
Status ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.
balances[]object[]selalu
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.Detail
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.
active_store_countintegerselaluJumlah toko aktif yang saat ini memilih aset ini. Ini gambaran penerimaan; pelacakan saldo hanya baca tetap independen.
active_store_ids[]UUID[]selaluToko aktif dalam proyek ini yang saat ini menerima aset. Ini memungkinkan pemfilteran toko lokal yang presisi tanpa permintaan API lain.
tracking_activebooleanselaluApakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.Detail
Apakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.
balancedecimal string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
balance_atomicinteger string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
statuspending | refreshing | fresh | stale | errorselaluStatus pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.Detail
Status pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.
total_value_usddecimal string | nullselaluJumlah saldo sebagai referensi yang memiliki harga USD terkini.
balance_statuspending | refreshing | fresh | stale | error | unknownselaluKebaruan cache gabungan; unknown adalah cadangan defensif dan tidak satu pun status ini membuktikan penyelesaian faktur.
balance_checked_attimestamp | nullselaluPemeriksaan saldo berhasil paling lama yang relevan dan diwakili oleh agregat.
recent_payments[]object[]selalu
Hingga tiga observasi valid terbaru berstatus detected, confirming, atau final yang diatribusikan ke dompet persis ini.
invoice_public_idUUIDselaluIdentitas faktur yang ditampilkan kepada pelanggan yang terkait dengan observasi.
statusdetected | confirming | finalselaluStatus observasi valid saat ini. Observasi reorged, replaced, dan invalid dikecualikan.
wallet_readinessreadiness enumselaluunsupported, 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, atau ready.Detail
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, atau ready.
receive_readinessobject | null5.5.0+
Penilaian penyiapan penerimaan proyek bersama. Mencakup pemeriksaan dompet dan penyedia pemindai independen, terpisah dari kebaruan saldo serta gas pengiriman. Null jika tidak ada kebijakan proyek. Mata uang/kurs faktur diperiksa saat membuat faktur.Detail
Penilaian penyiapan penerimaan proyek bersama. Mencakup pemeriksaan dompet dan penyedia pemindai independen, terpisah dari kebaruan saldo serta gas pengiriman. Null jika tidak ada kebijakan proyek. Mata uang/kurs faktur diperiksa saat membuat faktur.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
Catatan penggunaan
- Body adalah penggantian kebijakan penuh dan menolak kolom tidak dikenal.
- Pengaktifan proyek sendiri tidak memilih aset untuk toko mana pun.
Kesalahan
GETJelajahi kandidat token pembayaran/v1/projects/{project_id}/payment-token-candidatesHanya baca
Mencari pemetaan kontrak CoinGecko dalam cache lokal hanya pada blockchain yang pemindai faktur token dan adapter saldonya sudah diimplementasikan. Hasilnya adalah kandidat penemuan, bukan aset pembayaran tepercaya.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | direkomendasikan | application/json |
Parameter path
Parameter kueri
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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
}
]
}Kolom respons
data[]object[]
contract_addressstringselaluKontrak atau mint yang cocok; diverifikasi on-chain sebelum pendaftaran.
market_cap_rankinteger | nullselaluPeringkat penemuan, bukan sinyal kepercayaan atau kesiapan pembayaran.
scanner_readybooleanselaluTrue hanya untuk kandidat pada jalur token yang diimplementasikan build ini.
Catatan penggunaan
- Adapter token yang didukung: ERC-20 pada Ethereum, Base, BNB Chain, HyperEVM, Avalanche, Polygon, Arbitrum, dan Optimism; SPL pada Solana.
- Blockchain katalog yang tidak didukung ditolak, bukan ditampilkan seolah bisa dipilih.
- Peringkat, ikon, dan harga CoinGecko adalah data penemuan sebagai referensi.
Kesalahan
POSTVerifikasi dan daftarkan token/v1/projects/{project_id}/payment-token-assetsBaca + tulis
Mempromosikan satu kandidat terkini ke registri pembayaran persisten hanya setelah node yang dikonfigurasi memverifikasi identitas blockchain, identitas kontrak/mint, desimal, dan kueri saldo yang dapat digunakan. Pendaftaran tidak pernah mempercayai metadata CoinGecko saja, dan setiap proyek dibatasi 20 aset token terdaftar.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | wajib | application/json |
| Accept | direkomendasikan | application/json |
Parameter path
Permintaan
: "${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))Body permintaan
chain_slugstringwajibethereum, base, bnb-chain, hyperliquid, avalanche, polygon, arbitrum, optimism, atau solana.
coingecko_idstringwajibIdentitas kandidat persis yang dikembalikan pencarian token. Pertahankan garis bawah atau tanda hubung awal, seperti _ atau -6. Jangan turunkan ID ini dari nama atau ticker token.Detail
Identitas kandidat persis yang dikembalikan pencarian token. Pertahankan garis bawah atau tanda hubung awal, seperti _ atau -6. Jangan turunkan ID ini dari nama atau ticker token.
Respons 201 application/json
Contoh respons
{
"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"
}
}Kolom respons
dataobject
Catatan penggunaan
- Aktifkan aset proyek native blockchain sebelum mendaftarkan tokennya.
- Proyek bisa mendaftarkan paling banyak 20 aset token; kandidat baru di atas batas tersebut mengembalikan token_chain_not_ready (409). Menggunakan kembali aset yang sudah terdaftar tidak memakai slot lain.
- Verifikasi node bisa lebih lama daripada pembacaan katalog; gunakan batas waktu klien eksplisit.
- Setelah pendaftaran, pilih aset untuk setiap toko yang seharusnya menawarkannya.
Kesalahan
GETTemukan pool DEX token kustom/v1/projects/{project_id}/payment-token-dex-poolsHanya baca
Temukan hingga 12 pool yang memenuhi syarat berdasarkan blockchain dan kontrak token dasar secara persis melalui DEX Screener, diurutkan menurut likuiditas. Ini tidak mendaftarkan atau mengaktifkan token.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
Parameter path
Parameter kueri
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{"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"}]}Kolom respons
data[]object[]
pair_addressstringselaluPengenal pool persis, ID bursa (mis. uniswap/pancakeswap), dan ticker pasangan khusus tampilan.
dex_idstringselaluPengenal pool persis, ID bursa (mis. uniswap/pancakeswap), dan ticker pasangan khusus tampilan.
quote_symbolstringselaluPengenal pool persis, ID bursa (mis. uniswap/pancakeswap), dan ticker pasangan khusus tampilan.
price_usddecimal stringselaluHarga USD token dasar yang diminta dan total likuiditas pool. Memerlukan likuiditas setidaknya $10,000 dan satu perdagangan dalam satu jam terakhir.
liquidity_usddecimal stringselaluHarga USD token dasar yang diminta dan total likuiditas pool. Memerlukan likuiditas setidaknya $10,000 dan satu perdagangan dalam satu jam terakhir.
fetched_atRFC 3339 timestampselaluWaktu server mengambil observasi penyedia, bukan stempel waktu perdagangan on-chain.
Catatan penggunaan
- Array data kosong berarti tidak ditemukan pool yang memenuhi syarat. Hanya pool yang token dasarnya merupakan kontrak persis yang diminta yang dikembalikan; harga USD sisi kuotasi tidak pernah diasumsikan.
- Pencantuman DEX bukan audit keamanan. Likuiditas minimum dan aktivitas terbaru mengurangi kuotasi yang tidak dapat digunakan, tetapi tidak mencegah manipulasi pasar.
- Uniswap, PancakeSwap, dan DEX terindeks lainnya didukung jika pemindai blockchain yang ada mendukung token. Akses API tetap dibatasi ke proyek dan dibatasi lajunya. Panggilan penyedia juga dijalankan secara berurutan dan dibatasi.
Kesalahan
POSTTambahkan atau ubah harga token kustom/v1/projects/{project_id}/payment-token-assets/customBaca + tulis
Memverifikasi kontrak kustom menggunakan node blockchain yang dikonfigurasi dan mendaftarkannya tanpa memerlukan pencantuman CoinGecko. Harga USD tetap atau pool DEX otomatis terpilih milik proyek ini, bukan milik ticker atau proyek lain. Mengulangi identitas yang sama memperbarui harga proyeknya tanpa mengubah kebijakan aktif/nonaktif yang ada.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | wajib | application/json |
Parameter path
Permintaan
: "${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))Body permintaan
chain_slugstringwajibethereum, base, bnb-chain, hyperliquid, avalanche, polygon, arbitrum, optimism, atau solana. Tetap untuk kontrak ini.
contract_addressstringwajibKontrak ERC-20 (0x ditambah 40 karakter heksadesimal), atau mint SPL klasik. Node memverifikasi identitas jaringan dan desimal persis; desimal serta URL RPC yang diberikan pemanggil ditolak.Detail
Kontrak ERC-20 (0x ditambah 40 karakter heksadesimal), atau mint SPL klasik. Node memverifikasi identitas jaringan dan desimal persis; desimal serta URL RPC yang diberikan pemanggil ditolak.
namestringwajibNama tampilan (1–80 karakter) dan ticker (1–16 huruf/angka/titik/garis bawah/tanda hubung, karakter pertama alfanumerik). Identitas yang sudah ada tidak bisa diganti namanya melalui endpoint ini.Detail
Nama tampilan (1–80 karakter) dan ticker (1–16 huruf/angka/titik/garis bawah/tanda hubung, karakter pertama alfanumerik). Identitas yang sudah ada tidak bisa diganti namanya melalui endpoint ini.
symbolstringwajibNama tampilan (1–80 karakter) dan ticker (1–16 huruf/angka/titik/garis bawah/tanda hubung, karakter pertama alfanumerik). Identitas yang sudah ada tidak bisa diganti namanya melalui endpoint ini.Detail
Nama tampilan (1–80 karakter) dan ticker (1–16 huruf/angka/titik/garis bawah/tanda hubung, karakter pertama alfanumerik). Identitas yang sudah ada tidak bisa diganti namanya melalui endpoint ini.
price_modefixed | dexopsionalBawaan fixed untuk kompatibilitas mundur. DEX menggunakan pool tertentu yang ditemukan untuk blockchain dan kontrak persis.
price_usddecimal stringmode fixedNilai USD tetap SATU token, positif, paling banyak 30 desimal, maksimum 1000000000000000000000000. Tanpa eksponen atau float. Jangan sertakan dalam mode dex.
dex_pair_addressstringmode dexAlamat pool dari payment-token-dex-pools. Wajib dalam mode dex; jangan sertakan dalam mode fixed. Server memeriksa ulang identitas pool, harga, likuiditas, dan aktivitas pada setiap penyimpanan.Detail
Alamat pool dari payment-token-dex-pools. Wajib dalam mode dex; jangan sertakan dalam mode fixed. Server memeriksa ulang identitas pool, harga, likuiditas, dan aktivitas pada setiap penyimpanan.
Respons 200 application/json
Contoh respons
{"data":{"asset_id":"44444444-4444-4444-8444-444444444444"}}Kolom respons
Catatan penggunaan
- Setelah pendaftaran, pilih asset_id pada endpoint payment-assets toko; pendaftaran saja tidak pernah mengaktifkan metode toko.
- Token kustom dan katalog berbagi batas 20 token per proyek. Kontrak yang sama pada blockchain berbeda adalah aset pembayaran berbeda.
- Kontrak katalog yang sudah ada mengembalikan 409: gunakan pendaftaran katalog untuk mempertahankan kurs pasar otomatis. Ticker kustom tidak pernah meminjam harga token dengan nama yang sama.
- Harga tetap adalah perkiraan operator. Harga DEX otomatis merupakan observasi spot dari pool terpilih melalui DEX Screener, bukan oracle yang tahan manipulasi. Spread toko dan pembulatan ke atas tetap berlaku, dengan kurs fiat terbaru. Kuotasi yang sudah diterbitkan tetap sama.
- Untuk mode DEX, temukan pool terlebih dahulu, lalu kirim price_mode: dex dan dex_pair_address, tanpa price_usd. Tugas latar belakang bersama menyegarkan pool terpilih setiap menit. Pemeriksaan gagal atau harga lebih dari lima menit menghapus token ini dari kuotasi baru; tidak ada peralihan diam-diam ke harga tetap atau ticker.
- Hanya token ERC-20 standar dan SPL klasik yang diterima. Token-2022/ekstensi dan blockchain khusus native ditolak. Verifikasi teknis bukan audit keamanan penerbit/kontrak; token dengan fee-on-transfer, rebasing, atau daftar hitam bisa berperilaku tidak kompatibel.
- Gunakan batas waktu klien setidaknya 60 detik. Verifikasi dibatasi dan bisa mencoba node cadangan. Input tidak valid mengembalikan 400; pemeriksaan blockchain/kontrak gagal mengembalikan 422; konflik identitas atau batas mengembalikan 409.
Kesalahan
GETDaftar metode pembayaran toko/v1/projects/{project_id}/stores/{store_id}/payment-assetsHanya baca
Mencantumkan aset on-chain dalam data dan kesiapan Lightning terpisah dalam lightning. Metode on-chain memerlukan dompet blockchain yang siap. Lightning menggunakan koneksi penerimaan eksternal terverifikasi yang dipilih di toko, independen dari dompet Bitcoin on-chain.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | direkomendasikan | application/json |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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 }
}Kolom respons
data[]object[]
assetobjectselalu
Aset native atau token terverifikasi yang terlihat oleh proyek.
asset_kindnative | tokenselaluApakah penyelesaian menggunakan mata uang blockchain atau kontrak/mint terverifikasi.
payment_railstringselaluJalur runtime: utxo, evm-native, solana-native, account-native, privacy-native, atau token-transfer.
contract_addressstring | nullselaluKontrak ERC-20 kanonis atau mint SPL untuk token; null untuk aset native.
coingecko_idstring | nullselaluIdentitas penemuan/harga. Null untuk kontrak kustom; jangan pernah menyimpulkan harga pasar dari tickernya. Metadata CoinGecko saja tidak pernah membuat token bisa dipilih.
custom_tokenbooleanselaluKontrak kustom terverifikasi on-chain dengan harga USD tetap atau pool DEX terpilih yang berlaku dalam proyek.
token_standarderc20 | spl-token | nullselaluStandar token runtime terverifikasi; null untuk aset native.
metadata_verified_attimestamp | nullselaluWaktu verifikasi metadata on-chain untuk token yang dipromosikan.
payment_supportedbooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
scanner_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
balance_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
default_finality_modeconfirmations | finalizedselaluModel finalitas bawaan yang diwarisi kebijakan proyek baru.
project_policyobject | nullselalu
Kebijakan proyek induk.
enabledbooleanwajibMengaktifkan atau menonaktifkan aset untuk proyek. Blockchain native harus diaktifkan sebelum token apa pun.
finality_modeconfirmations | finalizedwajibKebijakan finalitas yang didukung jalur aset. finalized memerlukan required_confirmations=1.
required_confirmationsintegerwajibJalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.Detail
Jalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.
selectedbooleanselaluApakah metode ini bagian dari konfigurasi yang diinginkan dan disimpan toko. Metode ditawarkan jika kebijakan proyek, dompet, adapter terinstal, dan harga valid. Gangguan pemindai sementara tidak menghapusnya dari faktur baru.Detail
Apakah metode ini bagian dari konfigurasi yang diinginkan dan disimpan toko. Metode ditawarkan jika kebijakan proyek, dompet, adapter terinstal, dan harga valid. Gangguan pemindai sementara tidak menghapusnya dari faktur baru.
confirmation_policyobject | nullselalu
Kebijakan toko efektif untuk aset yang dikonfigurasi proyek. Null jika tidak ada kebijakan proyek.
finality_modeconfirmations | finalizedselaluApakah penyelesaian menggunakan jumlah blok yang dapat dikonfigurasi atau finalitas jaringan.
project_required_confirmationsintegerselaluPengaturan bawaan proyek terkini yang digunakan faktur mendatang jika tidak ada pengesampingan toko.
override_required_confirmationsinteger | nullselaluJumlah khusus toko, atau null untuk mewarisi pengaturan bawaan proyek.
effective_required_confirmationsintegerselaluJumlah yang akan disimpan dalam snapshot faktur baru untuk toko dan aset ini.
editablebooleanselaluFalse untuk jaringan finalized yang kebijakan finalitasnya tidak bisa diganti.
minimum_required_confirmationsintegerselaluBatas bawah inklusif yang sesuai blockchain; 0 hanya ditampilkan pada jalur yang mendukung penerimaan saat deteksi.
walletobject | nullselalu
Dompet blockchain yang dibagi aset native dan token.
public_keystring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
primary_addressstring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
backup_confirmed_attimestamp | nullselaluBukan null setelah operator mengonfirmasi cadangan pemulihan.
activation_requiredbooleanselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
activation_verified_attimestamp|nullselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
receive_readinessobject | null5.5.0+
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.Detail
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
monero_wallet_rpcMoneroWalletRpcBinding | nullselaluStatus ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.Detail
Status ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.
balances[]object[]selalu
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.Detail
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.
active_store_countintegerselaluJumlah toko aktif yang saat ini memilih aset ini. Ini gambaran penerimaan; pelacakan saldo hanya baca tetap independen.
active_store_ids[]UUID[]selaluToko aktif dalam proyek ini yang saat ini menerima aset. Ini memungkinkan pemfilteran toko lokal yang presisi tanpa permintaan API lain.
tracking_activebooleanselaluApakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.Detail
Apakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.
balancedecimal string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
balance_atomicinteger string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
statuspending | refreshing | fresh | stale | errorselaluStatus pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.Detail
Status pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.
total_value_usddecimal string | nullselaluJumlah saldo sebagai referensi yang memiliki harga USD terkini.
balance_statuspending | refreshing | fresh | stale | error | unknownselaluKebaruan cache gabungan; unknown adalah cadangan defensif dan tidak satu pun status ini membuktikan penyelesaian faktur.
balance_checked_attimestamp | nullselaluPemeriksaan saldo berhasil paling lama yang relevan dan diwakili oleh agregat.
recent_payments[]object[]selalu
Hingga tiga observasi valid terbaru berstatus detected, confirming, atau final yang diatribusikan ke dompet persis ini.
invoice_public_idUUIDselaluIdentitas faktur yang ditampilkan kepada pelanggan yang terkait dengan observasi.
statusdetected | confirming | finalselaluStatus observasi valid saat ini. Observasi reorged, replaced, dan invalid dikecualikan.
wallet_readinessreadiness enumselaluHanya status dompet/kebijakan; gunakan receive_readiness untuk prasyarat pemindai.
receive_readinessobject | null5.5.0+
Penyiapan penerimaan bersama ditambah penerimaan toko. Menggunakan observasi cache; bukan pencadangan atau jaminan. Pembuatan memeriksa ulang persyaratan dan kurs faktur sebenarnya.Detail
Penyiapan penerimaan bersama ditambah penerimaan toko. Menggunakan observasi cache; bukan pencadangan atau jaminan. Pembuatan memeriksa ulang persyaratan dan kurs faktur sebenarnya.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
Catatan penggunaan
- selected adalah konfigurasi on-chain; wallet_readiness adalah gerbang kelayakan terkininya.
- Anggota respons lightning berisi payment_rail: lightning, symbol: BTC, asset_decimals: 11, enabled, dan ready. Tidak pernah berisi kredensial node. Konfigurasikan metode ini di konsol toko; memperbarui array assets tidak mengubah Lightning.
- confirmation_policy hanya berlaku untuk metode on-chain. Lightning diselesaikan tanpa konfirmasi blok dan memerlukan jumlah BOLT11 penuh, tanpa toleransi pembayaran parsial.
- Metode native dan token pada satu blockchain menggunakan tujuan faktur yang sama untuk dompet blockchain tersebut.
- Ringkasan dompet tersemat hanya mencakup kesiapan dan membiarkan saldo kosong; gunakan rute dompet proyek khusus untuk nilai terkini.
Kesalahan
PUTGanti metode pembayaran toko/v1/projects/{project_id}/stores/{store_id}/payment-assetsBaca + tulis
Secara atomik mengganti seluruh subset aset berurutan toko dan mengembalikan daftar yang disegarkan. Aset yang tidak disertakan dibatalkan pilihannya.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | wajib | application/json |
| Accept | direkomendasikan | application/json |
Parameter path
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"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" }
]
}Kolom respons
data[]object[]
assetobjectselalu
Aset native atau token terverifikasi yang terlihat oleh proyek.
asset_kindnative | tokenselaluApakah penyelesaian menggunakan mata uang blockchain atau kontrak/mint terverifikasi.
payment_railstringselaluJalur runtime: utxo, evm-native, solana-native, account-native, privacy-native, atau token-transfer.
contract_addressstring | nullselaluKontrak ERC-20 kanonis atau mint SPL untuk token; null untuk aset native.
coingecko_idstring | nullselaluIdentitas penemuan/harga. Null untuk kontrak kustom; jangan pernah menyimpulkan harga pasar dari tickernya. Metadata CoinGecko saja tidak pernah membuat token bisa dipilih.
custom_tokenbooleanselaluKontrak kustom terverifikasi on-chain dengan harga USD tetap atau pool DEX terpilih yang berlaku dalam proyek.
token_standarderc20 | spl-token | nullselaluStandar token runtime terverifikasi; null untuk aset native.
metadata_verified_attimestamp | nullselaluWaktu verifikasi metadata on-chain untuk token yang dipromosikan.
payment_supportedbooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
scanner_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
balance_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
default_finality_modeconfirmations | finalizedselaluModel finalitas bawaan yang diwarisi kebijakan proyek baru.
project_policyobject | nullselalu
Kebijakan proyek induk.
enabledbooleanwajibMengaktifkan atau menonaktifkan aset untuk proyek. Blockchain native harus diaktifkan sebelum token apa pun.
finality_modeconfirmations | finalizedwajibKebijakan finalitas yang didukung jalur aset. finalized memerlukan required_confirmations=1.
required_confirmationsintegerwajibJalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.Detail
Jalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.
selectedbooleanselaluApakah metode ini bagian dari konfigurasi yang diinginkan dan disimpan toko. Metode ditawarkan jika kebijakan proyek, dompet, adapter terinstal, dan harga valid. Gangguan pemindai sementara tidak menghapusnya dari faktur baru.Detail
Apakah metode ini bagian dari konfigurasi yang diinginkan dan disimpan toko. Metode ditawarkan jika kebijakan proyek, dompet, adapter terinstal, dan harga valid. Gangguan pemindai sementara tidak menghapusnya dari faktur baru.
confirmation_policyobject | nullselalu
Kebijakan toko efektif untuk aset yang dikonfigurasi proyek. Null jika tidak ada kebijakan proyek.
finality_modeconfirmations | finalizedselaluApakah penyelesaian menggunakan jumlah blok yang dapat dikonfigurasi atau finalitas jaringan.
project_required_confirmationsintegerselaluPengaturan bawaan proyek terkini yang digunakan faktur mendatang jika tidak ada pengesampingan toko.
override_required_confirmationsinteger | nullselaluJumlah khusus toko, atau null untuk mewarisi pengaturan bawaan proyek.
effective_required_confirmationsintegerselaluJumlah yang akan disimpan dalam snapshot faktur baru untuk toko dan aset ini.
editablebooleanselaluFalse untuk jaringan finalized yang kebijakan finalitasnya tidak bisa diganti.
minimum_required_confirmationsintegerselaluBatas bawah inklusif yang sesuai blockchain; 0 hanya ditampilkan pada jalur yang mendukung penerimaan saat deteksi.
walletobject | nullselalu
Dompet blockchain yang dibagi aset native dan token.
public_keystring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
primary_addressstring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
backup_confirmed_attimestamp | nullselaluBukan null setelah operator mengonfirmasi cadangan pemulihan.
activation_requiredbooleanselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
activation_verified_attimestamp|nullselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
receive_readinessobject | null5.5.0+
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.Detail
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
monero_wallet_rpcMoneroWalletRpcBinding | nullselaluStatus ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.Detail
Status ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.
balances[]object[]selalu
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.Detail
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.
active_store_countintegerselaluJumlah toko aktif yang saat ini memilih aset ini. Ini gambaran penerimaan; pelacakan saldo hanya baca tetap independen.
active_store_ids[]UUID[]selaluToko aktif dalam proyek ini yang saat ini menerima aset. Ini memungkinkan pemfilteran toko lokal yang presisi tanpa permintaan API lain.
tracking_activebooleanselaluApakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.Detail
Apakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.
balancedecimal string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
balance_atomicinteger string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
statuspending | refreshing | fresh | stale | errorselaluStatus pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.Detail
Status pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.
total_value_usddecimal string | nullselaluJumlah saldo sebagai referensi yang memiliki harga USD terkini.
balance_statuspending | refreshing | fresh | stale | error | unknownselaluKebaruan cache gabungan; unknown adalah cadangan defensif dan tidak satu pun status ini membuktikan penyelesaian faktur.
balance_checked_attimestamp | nullselaluPemeriksaan saldo berhasil paling lama yang relevan dan diwakili oleh agregat.
recent_payments[]object[]selalu
Hingga tiga observasi valid terbaru berstatus detected, confirming, atau final yang diatribusikan ke dompet persis ini.
invoice_public_idUUIDselaluIdentitas faktur yang ditampilkan kepada pelanggan yang terkait dengan observasi.
statusdetected | confirming | finalselaluStatus observasi valid saat ini. Observasi reorged, replaced, dan invalid dikecualikan.
wallet_readinessreadiness enumselaluHanya status dompet/kebijakan; gunakan receive_readiness untuk prasyarat pemindai.
receive_readinessobject | null5.5.0+
Penyiapan penerimaan bersama ditambah penerimaan toko. Menggunakan observasi cache; bukan pencadangan atau jaminan. Pembuatan memeriksa ulang persyaratan dan kurs faktur sebenarnya.Detail
Penyiapan penerimaan bersama ditambah penerimaan toko. Menggunakan observasi cache; bukan pencadangan atau jaminan. Pembuatan memeriksa ulang persyaratan dan kurs faktur sebenarnya.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
Catatan penggunaan
- Array menerima paling banyak 64 aset dan urutan tampilan unik.
- Pilihan adalah konfigurasi yang diinginkan dan disimpan, serta bisa disiapkan sebelum dompet dicadangkan atau saat blockchain dijeda. Pembuatan faktur tetap hanya menawarkan metode yang kebijakan proyek, kebijakan induk native, dompet, dan pemeriksaan runtime-nya siap.
- Kirim array assets kosong untuk mengonfigurasi tanpa metode pembayaran.
Kesalahan
PUTTetapkan kebijakan konfirmasi toko/v1/projects/{project_id}/stores/{store_id}/payment-assets/{asset_id}/confirmation-policyBaca + tulis
Menetapkan atau menghapus satu pengesampingan konfirmasi khusus toko dan mengembalikan daftar metode pembayaran toko yang disegarkan. Aset harus sudah dipilih untuk toko. Konfigurasi tetap tersedia saat proyek, toko, blockchain, atau dompet dijeda.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Content-Type | wajib | application/json |
| Accept | direkomendasikan | application/json |
Parameter path
Permintaan
: "${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))Body permintaan
Respons 200 application/json
Contoh respons
{
"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"
}
]
}Kolom respons
data[]object[]
assetobjectselalu
Aset native atau token terverifikasi yang terlihat oleh proyek.
asset_kindnative | tokenselaluApakah penyelesaian menggunakan mata uang blockchain atau kontrak/mint terverifikasi.
payment_railstringselaluJalur runtime: utxo, evm-native, solana-native, account-native, privacy-native, atau token-transfer.
contract_addressstring | nullselaluKontrak ERC-20 kanonis atau mint SPL untuk token; null untuk aset native.
coingecko_idstring | nullselaluIdentitas penemuan/harga. Null untuk kontrak kustom; jangan pernah menyimpulkan harga pasar dari tickernya. Metadata CoinGecko saja tidak pernah membuat token bisa dipilih.
custom_tokenbooleanselaluKontrak kustom terverifikasi on-chain dengan harga USD tetap atau pool DEX terpilih yang berlaku dalam proyek.
token_standarderc20 | spl-token | nullselaluStandar token runtime terverifikasi; null untuk aset native.
metadata_verified_attimestamp | nullselaluWaktu verifikasi metadata on-chain untuk token yang dipromosikan.
payment_supportedbooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
scanner_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
balance_readybooleanselaluGerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.Detail
Gerbang registri saat build. scanner_ready berarti runtime pemindai pembayaran terinstal; konfirmasi pembayaran memerlukan jumlah penyedia sehat dengan peran persis yang dikonfigurasi (bawaan 2, opsional 1); ketersediaan pemindai sementara tidak memblokir pembuatan faktur mulai 6.0.6. balance_ready hanya true untuk adapter saldo yang diimplementasikan.
default_finality_modeconfirmations | finalizedselaluModel finalitas bawaan yang diwarisi kebijakan proyek baru.
project_policyobject | nullselalu
Kebijakan proyek induk.
enabledbooleanwajibMengaktifkan atau menonaktifkan aset untuk proyek. Blockchain native harus diaktifkan sebelum token apa pun.
finality_modeconfirmations | finalizedwajibKebijakan finalitas yang didukung jalur aset. finalized memerlukan required_confirmations=1.
required_confirmationsintegerwajibJalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.Detail
Jalur Bitcoin dan EVM menerima nol; jalur konfirmasi lain memerlukan setidaknya satu, jalur khusus finalized memerlukan tepat satu, dan jalur EVM dibatasi 0–48 agar setiap transfer tetap dalam jendela replay transaksi.
selectedbooleanselaluApakah metode ini bagian dari konfigurasi yang diinginkan dan disimpan toko. Metode ditawarkan jika kebijakan proyek, dompet, adapter terinstal, dan harga valid. Gangguan pemindai sementara tidak menghapusnya dari faktur baru.Detail
Apakah metode ini bagian dari konfigurasi yang diinginkan dan disimpan toko. Metode ditawarkan jika kebijakan proyek, dompet, adapter terinstal, dan harga valid. Gangguan pemindai sementara tidak menghapusnya dari faktur baru.
confirmation_policyobject | nullselalu
Kebijakan toko efektif untuk aset yang dikonfigurasi proyek. Null jika tidak ada kebijakan proyek.
finality_modeconfirmations | finalizedselaluApakah penyelesaian menggunakan jumlah blok yang dapat dikonfigurasi atau finalitas jaringan.
project_required_confirmationsintegerselaluPengaturan bawaan proyek terkini yang digunakan faktur mendatang jika tidak ada pengesampingan toko.
override_required_confirmationsinteger | nullselaluJumlah khusus toko, atau null untuk mewarisi pengaturan bawaan proyek.
effective_required_confirmationsintegerselaluJumlah yang akan disimpan dalam snapshot faktur baru untuk toko dan aset ini.
editablebooleanselaluFalse untuk jaringan finalized yang kebijakan finalitasnya tidak bisa diganti.
minimum_required_confirmationsintegerselaluBatas bawah inklusif yang sesuai blockchain; 0 hanya ditampilkan pada jalur yang mendukung penerimaan saat deteksi.
walletobject | nullselalu
Dompet blockchain yang dibagi aset native dan token.
public_keystring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
primary_addressstring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
backup_confirmed_attimestamp | nullselaluBukan null setelah operator mengonfirmasi cadangan pemulihan.
activation_requiredbooleanselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
activation_verified_attimestamp|nullselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
receive_readinessobject | null5.5.0+
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.Detail
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
monero_wallet_rpcMoneroWalletRpcBinding | nullselaluStatus ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.Detail
Status ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.
balances[]object[]selalu
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.Detail
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.
active_store_countintegerselaluJumlah toko aktif yang saat ini memilih aset ini. Ini gambaran penerimaan; pelacakan saldo hanya baca tetap independen.
active_store_ids[]UUID[]selaluToko aktif dalam proyek ini yang saat ini menerima aset. Ini memungkinkan pemfilteran toko lokal yang presisi tanpa permintaan API lain.
tracking_activebooleanselaluApakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.Detail
Apakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.
balancedecimal string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
balance_atomicinteger string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
statuspending | refreshing | fresh | stale | errorselaluStatus pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.Detail
Status pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.
total_value_usddecimal string | nullselaluJumlah saldo sebagai referensi yang memiliki harga USD terkini.
balance_statuspending | refreshing | fresh | stale | error | unknownselaluKebaruan cache gabungan; unknown adalah cadangan defensif dan tidak satu pun status ini membuktikan penyelesaian faktur.
balance_checked_attimestamp | nullselaluPemeriksaan saldo berhasil paling lama yang relevan dan diwakili oleh agregat.
recent_payments[]object[]selalu
Hingga tiga observasi valid terbaru berstatus detected, confirming, atau final yang diatribusikan ke dompet persis ini.
invoice_public_idUUIDselaluIdentitas faktur yang ditampilkan kepada pelanggan yang terkait dengan observasi.
statusdetected | confirming | finalselaluStatus observasi valid saat ini. Observasi reorged, replaced, dan invalid dikecualikan.
wallet_readinessreadiness enumselaluHanya status dompet/kebijakan; gunakan receive_readiness untuk prasyarat pemindai.
receive_readinessobject | null5.5.0+
Penyiapan penerimaan bersama ditambah penerimaan toko. Menggunakan observasi cache; bukan pencadangan atau jaminan. Pembuatan memeriksa ulang persyaratan dan kurs faktur sebenarnya.Detail
Penyiapan penerimaan bersama ditambah penerimaan toko. Menggunakan observasi cache; bukan pencadangan atau jaminan. Pembuatan memeriksa ulang persyaratan dan kurs faktur sebenarnya.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
Catatan penggunaan
- Gunakan {"strategy":"inherit"} untuk menghapus pengesampingan toko dan mengikuti pengaturan bawaan proyek saat ini untuk faktur mendatang.
- Jaringan finalized mengembalikan editable false dan menggunakan Finalitas jaringan; tidak menerima pengesampingan jumlah blok kustom.
- Nilai 0 berarti menerima saat deteksi tanpa konfirmasi jaringan dan tanpa perlindungan reorg. Hanya diterima jika minimum_required_confirmations adalah 0.
- Perubahan kebijakan hanya memengaruhi faktur baru. Faktur yang ada mempertahankan snapshot kebijakan konfirmasi proyek/toko yang dicatat saat pembuatan.
- Pembaruan dilakukan satu aset setiap kali; jalankan perubahan bersamaan untuk aset toko yang sama secara berurutan dan gunakan respons yang disegarkan sebagai status terkini.
Kesalahan
GETDaftar dompet dan saldo proyek/v1/projects/{project_id}/walletsHanya baca
Mengembalikan metadata dompet publik beserta setiap aset terdaftar yang mampu dibaca saldonya pada blockchain dan jaringan dompet secara persis. Semua 30 jalur blockchain native tercakup; aset ERC-20 dan SPL terverifikasi juga dilacak. Aset langsung muncul, bahkan sebelum pemindaian pertama atau saat tidak diterima untuk pembayaran. project_enabled melaporkan penerimaan pembayaran; tracking_active secara independen melaporkan kelayakan penyegaran hanya baca. Monero memerlukan wallet-RPC hanya lihat eksternal yang terikat ke proyek. Pindai saldo di konsol memprioritaskan pembacaan terbatas dengan progres/kesalahan per aset; hanya siklus lengkap yang memperbarui total terbaru. Penyelesaian faktur tetap digerakkan pemantauan tingkat transaksi dan kebijakan konfirmasi, bukan saldo cache ini.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | direkomendasikan | application/json |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}
]
}Kolom respons
data[]object[]
public_keystring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
primary_addressstring | nullselaluIdentitas dompet publik; tidak ada frasa seed atau kunci privat yang ditampilkan.
backup_confirmed_attimestamp | nullselaluBukan null setelah operator mengonfirmasi cadangan pemulihan.
activation_requiredbooleanselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
activation_verified_attimestamp|nullselaluAkun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.Detail
Akun bersama XRP dan Stellar tetap tidak tersedia sampai operator mendanai alamat yang ditampilkan dan penyedia pemindai yang dikonfigurasi memverifikasi akun persis tersebut. Bukti persisten tidak kedaluwarsa; kesehatan pemindai langsung diperiksa terpisah untuk verifikasi pembayaran, bukan pembuatan faktur.
receive_readinessobject | null5.5.0+
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.Detail
Disertakan pada daftar dompet: penyiapan penerimaan proyek dan prasyarat pemindai blockchain. Terpisah dari saldo, gas token, dan kesiapan pengiriman. Respons dompet lain mungkin membiarkannya null.
readybooleanselaluPemeriksaan penyiapan penerimaan lulus. Tidak menjelaskan kesiapan pembelanjaan, gas, penyegaran saldo, atau jaminan kuotasi mendatang.
invoice_creatableboolean6.0.6+Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.Detail
Konfigurasi mengizinkan metode faktur meskipun ada peringatan pemindai sementara. Harga mata uang diperiksa saat pembuatan. Ini bukan verifikasi pembayaran: ready bisa false sementara invoice_creatable true. Dompet yang belum ada, kebijakan nonaktif, dan adapter yang tidak didukung tetap gagal dengan aman.
checked_attimestampselaluWaktu penilaian. Daftar tidak melakukan permintaan jaringan atau alokasi alamat.
issues[]object[]selalu
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.Detail
Kosong saat siap; jika tidak, berisi peringatan penerimaan atau penghalang konfigurasi. Periksa invoice_creatable untuk membedakan peringatan pemindai sementara dari kegagalan penyiapan faktur.
chain_slugstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_idUUIDjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
asset_tickerstringjika diketahuiMengidentifikasi blockchain dan aset terkait. Lightning bisa tidak menyertakan asset_id.
reason_codestringselaluscanner_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, atau asset_not_accepted.Detail
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, atau asset_not_accepted.
messagestringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
actionstringjika tersediaPenjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.Detail
Penjelasan untuk merchant dan pengenal tindakan: chain_connections, wallets, rates, payment_methods, project_settings, atau store_settings. Tanpa kredensial atau URL penyedia privat.
required_endpoint_rolestring | nullon-chainPeran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.Detail
Peran API pemindai yang diutamakan (kolom lama). Gunakan accepted_endpoint_roles untuk daftar kompatibilitas lengkap. Kesehatan node dasar tidak membuktikan dukungan riwayat pembayaran.
accepted_endpoint_roles[]string[] | nullon-chainDialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.Detail
Dialek API yang kompatibel, bukan bukti riwayat atau kapasitas endpoint. node-rpc mentah mendukung BTC/BCH/LTC/DOGE/DASH dan ZEC transparan (blok terdekode lengkap, 1–48 konfirmasi), TRX native tersolidifikasi, ALGO native melalui algod, XTZ melalui Octez, DOT Asset Hub final melalui metadata SCALE, dan XLM native melalui Stellar RPC dengan ID memo faktur. Riwayat yang dipangkas atau tidak lengkap tidak memenuhi syarat. Adapter mentah ini tidak menambahkan jalur token. API terindeks tetap menjadi alternatif; lihat tabel jalur di bawah. Sumber campuran mentah/terindeks memverifikasi jendela terbatas secara independen; bawaan tetap dua penyedia independen, bukan alias satu operator. Ketinggian node dasar, info blockchain ORDnet, dan relay EVM untuk jalur non-EVM bukan bukti penerimaan. Monero tetap memerlukan wallet-RPC hanya lihat yang terikat ke proyek.
usable_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
required_independent_providersintegeron-chainSlot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.Detail
Slot verifikasi yang bisa digunakan, dibatasi dua. required_independent_providers adalah pengaturan blockchain: bawaan 2, atau 1 setelah pilihan eksplisit administrator. Dalam mode dua penyedia, kunci penyedia DAN host harus berbeda. Sumber nonaktif, usang (lebih dari sepuluh menit), atau sedang dalam masa tunggu tidak mengisi slot. Lightning menggunakan aturan koneksinya sendiri.
last_checked_attimestamp | nullon-chainPemeriksaan kesehatan endpoint cocok terbaru, terpisah dari waktu penilaian.
monero_wallet_rpcMoneroWalletRpcBinding | nullselaluStatus ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.Detail
Status ikatan wallet-RPC hanya lihat eksternal untuk Monero yang telah dibersihkan dari informasi sensitif. Mencakup endpoint, mode autentikasi, alamat utama account-0, penanda/ketinggian bukti teknis, dan stempel waktu pernyataan operator; kredensial, kunci dompet, serta file dompet tidak pernah diserialisasi.
balances[]object[]selalu
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.Detail
Saldo dalam cache untuk masing-masing dari 30 jalur blockchain native, ditambah aset ERC-20 dan SPL terverifikasi. Monero memerlukan wallet-RPC hanya lihat eksternal yang dikonfigurasi.
active_store_countintegerselaluJumlah toko aktif yang saat ini memilih aset ini. Ini gambaran penerimaan; pelacakan saldo hanya baca tetap independen.
active_store_ids[]UUID[]selaluToko aktif dalam proyek ini yang saat ini menerima aset. Ini memungkinkan pemfilteran toko lokal yang presisi tanpa permintaan API lain.
tracking_activebooleanselaluApakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.Detail
Apakah dompet yang mampu membaca ini dan aset terdaftar pada blockchain yang sama memenuhi syarat untuk penyegaran saldo latar belakang. Sakelar proyek dan penerimaan metode pembayaran tidak menjeda pelacakan hanya baca.
balancedecimal string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
balance_atomicinteger string|nullselaluSaldo tampilan dan atomik presisi di seluruh alamat utama dompet serta alamat faktur yang diterbitkan. Null selama nilai lengkap belum tersedia.
statuspending | refreshing | fresh | stale | errorselaluStatus pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.Detail
Status pemindaian dalam cache. refreshing bisa mempertahankan saldo lengkap: gunakan checked_at untuk usianya. Pending berarti belum ada snapshot lengkap. Tidak satu pun status ini membuktikan transfer tertunda atau faktur selesai.
total_value_usddecimal string | nullselaluJumlah saldo sebagai referensi yang memiliki harga USD terkini.
balance_statuspending | refreshing | fresh | stale | error | unknownselaluKebaruan cache gabungan; unknown adalah cadangan defensif dan tidak satu pun status ini membuktikan penyelesaian faktur.
balance_checked_attimestamp | nullselaluPemeriksaan saldo berhasil paling lama yang relevan dan diwakili oleh agregat.
recent_payments[]object[]selalu
Hingga tiga observasi valid terbaru berstatus detected, confirming, atau final yang diatribusikan ke dompet persis ini.
invoice_public_idUUIDselaluIdentitas faktur yang ditampilkan kepada pelanggan yang terkait dengan observasi.
statusdetected | confirming | finalselaluStatus observasi valid saat ini. Observasi reorged, replaced, dan invalid dikecualikan.
Catatan penggunaan
- Rute bearer ini tidak pernah mengembalikan frasa pemulihan, kunci privat, rahasia terenkripsi, atau metode pembelanjaan.
- Aset pada blockchain yang sama yang baru didaftarkan dikembalikan dengan saldo null dan status pending sebelum pemindaian pertama selesai; tidak pernah dilaporkan sebagai nol yang direkayasa.
- Menonaktifkan proyek, dompet untuk penerimaan pembayaran, jalur native, atau aset individual tidak menghentikan pelacakan saldo hanya baca: dompet aktif dan nonaktif dengan alamat utama terus menyegarkan setiap aset terdaftar yang didukung pada blockchain yang sama. Dompet pending dan error tidak dipindai.
- project_enabled hanya melaporkan kebijakan penerimaan aset proyek dan bisa false sementara tracking_active tetap true.
- balance dan balance_atomic adalah string presisi; price_usd, value_usd, dan total_value_usd bersifat referensi serta bisa null. Status saldo terbaru tidak menjamin harga pasar terbaru.
- Penilaian mengutamakan harga CoinGecko berusia hingga dua jam. Koin native dan USDC/USDT kanonis terverifikasi bisa beralih ke kuotasi USD Kraken/Binance aktif yang berusia hingga lima menit, penyedia utama lebih dahulu. Tidak mengasumsikan patokan dolar atau harga token kustom berdasarkan ticker saja; harga fixed/DEX proyek tetap terpisah. Kuotasi faktur tetap sama.
- Pending belum memiliki snapshot lengkap. Refreshing mempertahankan jumlah terakhir yang selesai dan checked_at; tidak berarti transfer blockchain tertunda. Jumlah stale/error juga bisa mempertahankan nilai lama. Jangan pernah menganggap cache tidak tersedia sebagai nol atau pembayaran hilang. Penyegaran rutin EVM/Solana menggunakan kembali alamat kosong yang baru diperiksa hingga 30 menit di antara audit, sementara alamat berisi dana, baru, dan berubah diperiksa ulang. Pindai saldo eksplisit di konsol meminta pemindaian penuh.
- recent_payments dibatasi tiga observasi per dompet dan mengecualikan riwayat yang dibatalkan validitasnya.
Kesalahan
POSTBuat faktur/v1/projects/{project_id}/stores/{store_id}/invoicesBaca + tulis
Membuat faktur secara atomik dengan tujuan dompet, kuotasi presisi terbaru, riwayat audit, dan entri kotak keluar notifikasi. Memutar ulang byte body mentah identik dengan kredensial dan Idempotency-Key yang sama mengembalikan faktur asli.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Idempotency-Key | wajib | 1–128 karakter ASCII terlihat yang unik tanpa spasi. |
| Content-Type | direkomendasikan | application/json. Handler body mentah saat ini mem-parsing JSON tanpa mewajibkan tipe media. |
| Accept | direkomendasikan | application/json |
Parameter path
project_idUUIDwajibSalin ID API Proyek dari Proyek → Pengaturan → ID API. Harus ditetapkan ke kredensial; pengenal proyek yang mudah dibaca tidak diterima.
store_idUUIDwajibSalin ID API Toko dari Proyek → Toko → pilih toko → Dasar → ID API. Wajib bahkan untuk toko bawaan; harus aktif dan milik project_id.
Permintaan
: "${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))Body permintaan
amountstringwajibString desimal biasa tanpa tanda; tanpa tanda positif/negatif atau eksponen, hingga 48 digit bilangan bulat dan 30 angka desimal. Harus positif secara bawaan. Toko bisa mengizinkan faktur bernilai nol di Toko → Faktur; total nol diselesaikan tanpa menerima dana, mengalokasikan alamat, atau biaya pemrosesan.Detail
String desimal biasa tanpa tanda; tanpa tanda positif/negatif atau eksponen, hingga 48 digit bilangan bulat dan 30 angka desimal. Harus positif secara bawaan. Toko bisa mengizinkan faktur bernilai nol di Toko → Faktur; total nol diselesaikan tanpa menerima dana, mengalokasikan alamat, atau biaya pemrosesan.
currencystring | nullopsionalMata uang fiat tiga huruf yang didukung, dinormalisasi menjadi huruf besar. Tidak disertakan atau null mewarisi mata uang faktur toko. Pembuatan juga memerlukan kurs konversi penagihan yang tersedia secara independen.Detail
Mata uang fiat tiga huruf yang didukung, dinormalisasi menjadi huruf besar. Tidak disertakan atau null mewarisi mata uang faktur toko. Pembuatan juga memerlukan kurs konversi penagihan yang tersedia secara independen.
payment_methods[]object[] | nullopsional
Pilih metode yang diaktifkan toko untuk faktur ini. Merchant 5.4.0+: abaikan pilihan tidak dikenal/nonaktif/tidak diterima; jika tidak ada yang cocok, gunakan pengaturan bawaan toko. Tidak disertakan/null juga menggunakan pengaturan bawaan toko; [] tidak valid. Tidak pernah mengaktifkan metode atau mengubah pengaturan toko. Lihat skema pilihan di bawah.Detail
Pilih metode yang diaktifkan toko untuk faktur ini. Merchant 5.4.0+: abaikan pilihan tidak dikenal/nonaktif/tidak diterima; jika tidak ada yang cocok, gunakan pengaturan bawaan toko. Tidak disertakan/null juga menggunakan pengaturan bawaan toko; [] tidak valid. Tidak pernah mengaktifkan metode atau mengubah pengaturan toko. Lihat skema pilihan di bawah.
chain_slugstringwajibSalin chain_slug di Proyek → Toko → Metode pembayaran, atau baca dari GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, seperti ethereum, base, atau bitcoin. Pasangan blockchain/jalur hanya boleh muncul satu kali.Detail
Salin chain_slug di Proyek → Toko → Metode pembayaran, atau baca dari GET /v1/projects/{project_id}/stores/{store_id}/payment-assets, seperti ethereum, base, atau bitcoin. Pasangan blockchain/jalur hanya boleh muncul satu kali.
asset_ids[]UUID[] | nullopsionalUUID asset.id on-chain, bukan alamat kontrak atau ID metode pembayaran faktur. Gunakan ini ATAU asset_tickers. Jangan sertakan kedua pemilih untuk semua aset aktif yang diterima pada blockchain ini. [] dan ID duplikat/nil tidak valid. Pada 5.4.0+, abaikan ID yang tidak aktif/diterima pada blockchain ini di toko ini; pilihan yang sepenuhnya tidak cocok menggunakan pengaturan bawaan toko.Detail
UUID asset.id on-chain, bukan alamat kontrak atau ID metode pembayaran faktur. Gunakan ini ATAU asset_tickers. Jangan sertakan kedua pemilih untuk semua aset aktif yang diterima pada blockchain ini. [] dan ID duplikat/nil tidak valid. Pada 5.4.0+, abaikan ID yang tidak aktif/diterima pada blockchain ini di toko ini; pilihan yang sepenuhnya tidak cocok menggunakan pengaturan bawaan toko.
asset_tickers[]string[] | nullopsionalMerchant 5.3.0+. Simbol seperti BTC, USDC, atau PEPE, dibatasi pada chain_slug dan toko ini. 1–64 ticker unik; spasi tepi dipangkas/tidak peka huruf besar-kecil, 1–40 huruf ASCII/angka/titik/garis bawah/tanda hubung. Gunakan ini ATAU asset_ids. Pada 5.4.0+, abaikan ticker tidak dikenal/nonaktif/tidak diterima. Simbol diterima yang ambigu tetap gagal: gunakan asset_ids. Metode aktif yang dipilih memerlukan dompet dan harga valid; gangguan pemindai on-chain sementara tidak memblokir pembuatan mulai 6.0.6. Lightning secara opsional hanya menerima BTC.Detail
Merchant 5.3.0+. Simbol seperti BTC, USDC, atau PEPE, dibatasi pada chain_slug dan toko ini. 1–64 ticker unik; spasi tepi dipangkas/tidak peka huruf besar-kecil, 1–40 huruf ASCII/angka/titik/garis bawah/tanda hubung. Gunakan ini ATAU asset_ids. Pada 5.4.0+, abaikan ticker tidak dikenal/nonaktif/tidak diterima. Simbol diterima yang ambigu tetap gagal: gunakan asset_ids. Metode aktif yang dipilih memerlukan dompet dan harga valid; gangguan pemindai on-chain sementara tidak memblokir pembuatan mulai 6.0.6. Lightning secara opsional hanya menerima BTC.
payment_railonchain | lightningopsionalBawaan onchain. Untuk memilih Bitcoin Lightning, gunakan {chain_slug: bitcoin, payment_rail: lightning} tanpa asset_ids; asset_tickers secara opsional boleh [BTC]. Bitcoin on-chain tidak mencakup Lightning. Koneksi Lightning toko harus sudah aktif dan siap.Detail
Bawaan onchain. Untuk memilih Bitcoin Lightning, gunakan {chain_slug: bitcoin, payment_rail: lightning} tanpa asset_ids; asset_tickers secara opsional boleh [BTC]. Bitcoin on-chain tidak mencakup Lightning. Koneksi Lightning toko harus sudah aktif dan siap.
order_idstring | nullopsionalReferensi pesanan merchant, 1–128 karakter setelah pemangkasan spasi; karakter kontrol ditolak.
emailstring | nullopsionalEmail pelanggan khusus merchant, dinormalisasi ke alamat ASCII praktis dengan paling banyak 254 karakter. Tidak disertakan atau null tidak menyimpan email.
descriptionstring | nullopsionalDeskripsi yang ditampilkan kepada pelanggan, 1–500 karakter; baris baru dan tab diizinkan.
expires_in_secondsinteger | nullopsionalMasa kuotasi faktur dari 300 sampai 86,400 detik; tidak disertakan atau null mewarisi kebijakan toko.
exchange_rate_spread_percentdecimal string | nullopsionalMarkup kuotasi dari 0 sampai 100, dengan paling banyak dua angka desimal. Tidak disertakan atau null mewarisi pengaturan bawaan toko; "0" menonaktifkannya untuk faktur ini. Diterapkan sebelum pembulatan ke atas, lalu dikunci. Tidak mengubah jumlah fiat faktur atau dasar biaya pemrosesan.Detail
Markup kuotasi dari 0 sampai 100, dengan paling banyak dua angka desimal. Tidak disertakan atau null mewarisi pengaturan bawaan toko; "0" menonaktifkannya untuk faktur ini. Diterapkan sebelum pembulatan ke atas, lalu dikunci. Tidak mengubah jumlah fiat faktur atau dasar biaya pemrosesan.
underpayment_tolerance_percentdecimal string | nullopsionalKekurangan yang diterima dari 0 sampai 99.99 dengan paling banyak dua angka desimal. Tidak disertakan atau null mewarisi pengaturan bawaan toko.
ipn_urlstring | nullopsionalCallback HTTPS publik, paling banyak 2,048 byte dan tanpa kredensial atau fragmen. Menggantikan pengaturan bawaan toko; null/tidak disertakan mewarisinya.
redirect_urlstring | nullopsionalURL sukses HTTPS yang digunakan setelah penyelesaian, paling banyak 2,048 byte dan tanpa kredensial tersemat. Tidak disertakan atau null mewarisi pengaturan bawaan toko dan tidak bisa menghapusnya.
cancel_urlstring | nullopsionalURL kembali HTTPS yang digunakan saat checkout berakhir tanpa pembayaran berhasil. Tidak disertakan atau null mewarisi pengaturan bawaan toko dan tidak bisa menghapusnya.
redirect_automaticallyboolean | nullopsionalTidak disertakan atau null mewarisi kebijakan toko. true memerlukan redirect_url efektif.
languagestring | nullopsionalBahasa pelanggan: en, de, es, pt-BR, it, ru, zh-CN, fr, ko, atau ja. pt berarti Portugis Brasil dan zh berarti Mandarin Sederhana. Tag regional yang didukung seperti de-DE dinormalisasi ke bahasa yang tercantum. Tidak disertakan atau null mewarisi bahasa toko. Bahasa konsol terpisah.Detail
Bahasa pelanggan: en, de, es, pt-BR, it, ru, zh-CN, fr, ko, atau ja. pt berarti Portugis Brasil dan zh berarti Mandarin Sederhana. Tag regional yang didukung seperti de-DE dinormalisasi ke bahasa yang tercantum. Tidak disertakan atau null mewarisi bahasa toko. Bahasa konsol terpisah.
checkout_appearanceobject | nullopsional
Pengaturan tampilan parsial untuk faktur ini. Tidak disertakan/null mengikuti desain toko saat ini. Objek, termasuk {}, membekukan desain dan gambar yang telah ditentukan saat pembuatan. Lihat skema pengesampingan di bawah; tanpa pengaturan keuangan, HTML, CSS, JavaScript, atau URL gambar jarak jauh.Detail
Pengaturan tampilan parsial untuk faktur ini. Tidak disertakan/null mengikuti desain toko saat ini. Objek, termasuk {}, membekukan desain dan gambar yang telah ditentukan saat pembuatan. Lihat skema pengesampingan di bawah; tanpa pengaturan keuangan, HTML, CSS, JavaScript, atau URL gambar jarak jauh.
inherit_default_storebooleanopsionaltrue memilih desain toko bawaan proyek sebagai dasar; jika tidak, gunakan desain efektif toko tujuan. Pengesampingan lalu diterapkan dan disimpan secara independen; nilai flag faktur hasilnya false.Detail
true memilih desain toko bawaan proyek sebagai dasar; jika tidak, gunakan desain efektif toko tujuan. Pengesampingan lalu diterapkan dan disimpan secara independen; nilai flag faktur hasilnya false.
introstringopsionalTeks biasa, masing-masing hingga 2,000 karakter. Intro muncul di atas, Outro di bawah pada setiap status. Baris baru dipertahankan; URL teks yang aman menjadi tautan. String kosong menghapus. customer_message lama diterima sebagai alias intro; jangan kirim keduanya.Detail
Teks biasa, masing-masing hingga 2,000 karakter. Intro muncul di atas, Outro di bawah pada setiap status. Baris baru dipertahankan; URL teks yang aman menjadi tautan. String kosong menghapus. customer_message lama diterima sebagai alias intro; jangan kirim keduanya.
outrostringopsionalTeks biasa, masing-masing hingga 2,000 karakter. Intro muncul di atas, Outro di bawah pada setiap status. Baris baru dipertahankan; URL teks yang aman menjadi tautan. String kosong menghapus. customer_message lama diterima sebagai alias intro; jangan kirim keduanya.Detail
Teks biasa, masing-masing hingga 2,000 karakter. Intro muncul di atas, Outro di bawah pada setiap status. Baris baru dipertahankan; URL teks yang aman menjadi tautan. String kosong menghapus. customer_message lama diterima sebagai alias intro; jangan kirim keduanya.
intro_font_sizeintegeropsionalPiksel: 12, 14, 16, 18, 20, atau 24. Bawaan 16 kecuali mewarisi nilai berbeda.
outro_font_sizeintegeropsionalPiksel: 12, 14, 16, 18, 20, atau 24. Bawaan 16 kecuali mewarisi nilai berbeda.
accent_colorstringopsional#RRGGBB. Latar belakang, kartu, dan tombol boleh kosong untuk warna otomatis. Kontras teks otomatis.
background_colorstringopsional#RRGGBB. Latar belakang, kartu, dan tombol boleh kosong untuk warna otomatis. Kontras teks otomatis.
card_colorstringopsional#RRGGBB. Latar belakang, kartu, dan tombol boleh kosong untuk warna otomatis. Kontras teks otomatis.
button_colorstringopsional#RRGGBB. Latar belakang, kartu, dan tombol boleh kosong untuk warna otomatis. Kontras teks otomatis.
imagesobjectopsional
Kunci logo_light, logo_dark, favicon. Kunci yang tidak disertakan mempertahankan gambar dasar; null menghapusnya. Objek {store_id: UUID, kind?: logo_light|logo_dark|favicon} memakai kembali gambar unggahan efektif toko tersebut dalam proyek yang SAMA. kind bawaan mengikuti kunci tujuan. Unggah di Toko → Checkout terlebih dahulu; salin ID API Toko dari Dasar → ID API. Gambar tidak tersedia atau ID lintas proyek mengembalikan 400. URL eksternal atau data gambar tidak diterima.Detail
Kunci logo_light, logo_dark, favicon. Kunci yang tidak disertakan mempertahankan gambar dasar; null menghapusnya. Objek {store_id: UUID, kind?: logo_light|logo_dark|favicon} memakai kembali gambar unggahan efektif toko tersebut dalam proyek yang SAMA. kind bawaan mengikuti kunci tujuan. Unggah di Toko → Checkout terlebih dahulu; salin ID API Toko dari Dasar → ID API. Gambar tidak tersedia atau ID lintas proyek mengembalikan 400. URL eksternal atau data gambar tidak diterima.
show_order_idbooleanopsionalTampilkan detail ID pesanan dan deskripsi teks biasa di bawah judul. details_expanded membuka detail ID pesanan sejak awal. Hanya tampilan, bukan penyamaran data.
show_descriptionbooleanopsionalTampilkan detail ID pesanan dan deskripsi teks biasa di bawah judul. details_expanded membuka detail ID pesanan sejak awal. Hanya tampilan, bukan penyamaran data.
details_expandedbooleanopsionalTampilkan detail ID pesanan dan deskripsi teks biasa di bawah judul. details_expanded membuka detail ID pesanan sejak awal. Hanya tampilan, bukan penyamaran data.
show_project_namebooleanopsionalMerchant 5.6.0+: tampilkan atau sembunyikan setiap nama pada header checkout pelanggan. Keduanya secara bawaan true. Juga tersedia di Toko → Checkout; diwarisi dan disimpan dalam snapshot faktur seperti pengaturan tampilan lain. Hanya tampilan, bukan penyamaran data.Detail
Merchant 5.6.0+: tampilkan atau sembunyikan setiap nama pada header checkout pelanggan. Keduanya secara bawaan true. Juga tersedia di Toko → Checkout; diwarisi dan disimpan dalam snapshot faktur seperti pengaturan tampilan lain. Hanya tampilan, bukan penyamaran data.
show_store_namebooleanopsionalMerchant 5.6.0+: tampilkan atau sembunyikan setiap nama pada header checkout pelanggan. Keduanya secara bawaan true. Juga tersedia di Toko → Checkout; diwarisi dan disimpan dalam snapshot faktur seperti pengaturan tampilan lain. Hanya tampilan, bukan penyamaran data.Detail
Merchant 5.6.0+: tampilkan atau sembunyikan setiap nama pada header checkout pelanggan. Keduanya secara bawaan true. Juga tersedia di Toko → Checkout; diwarisi dan disimpan dalam snapshot faktur seperti pengaturan tampilan lain. Hanya tampilan, bukan penyamaran data.
featured_chains[]string[]opsionalSlug blockchain berurutan, paling banyak 60 nilai unik (huruf kecil, angka, tanda hubung; hingga 64 karakter). [] menghapus. Hanya metode faktur yang tersedia yang diurutkan ulang.Detail
Slug blockchain berurutan, paling banyak 60 nilai unik (huruf kecil, angka, tanda hubung; hingga 64 karakter). [] menghapus. Hanya metode faktur yang tersedia yang diurutkan ulang.
featured_asset_ids[]UUID[]opsionalHingga 100 ID aset unik berurutan; [] menghapus. Aset bawaan boleh null. ID berasal dari payment-assets, bukan ID intent pembayaran. Ini tidak pernah mengaktifkan metode; pembayaran yang diterima dan preferensi pelanggan yang valid diprioritaskan.Detail
Hingga 100 ID aset unik berurutan; [] menghapus. Aset bawaan boleh null. ID berasal dari payment-assets, bukan ID intent pembayaran. Ini tidak pernah mengaktifkan metode; pembayaran yang diterima dan preferensi pelanggan yang valid diprioritaskan.
default_asset_idUUID|nullopsionalHingga 100 ID aset unik berurutan; [] menghapus. Aset bawaan boleh null. ID berasal dari payment-assets, bukan ID intent pembayaran. Ini tidak pernah mengaktifkan metode; pembayaran yang diterima dan preferensi pelanggan yang valid diprioritaskan.Detail
Hingga 100 ID aset unik berurutan; [] menghapus. Aset bawaan boleh null. ID berasal dari payment-assets, bukan ID intent pembayaran. Ini tidak pernah mengaktifkan metode; pembayaran yang diterima dan preferensi pelanggan yang valid diprioritaskan.
messagesobjectopsional
Objek bahasa dengan kunci en, de, es, pt-BR, it, ru, zh-CN, fr, ko, atau ja, dengan string biasa waiting, confirming, paid, underpaid, expired (masing-masing 500 karakter). Hanya bahasa/status yang diberikan yang berubah; {} menghapus semua pesan, {en:{}} menghapus bahasa Inggris, dan string status kosong menghapus status tersebut. Bahasa Inggris menjadi cadangan. Tidak mengganti status sebenarnya.Detail
Objek bahasa dengan kunci en, de, es, pt-BR, it, ru, zh-CN, fr, ko, atau ja, dengan string biasa waiting, confirming, paid, underpaid, expired (masing-masing 500 karakter). Hanya bahasa/status yang diberikan yang berubah; {} menghapus semua pesan, {en:{}} menghapus bahasa Inggris, dan string status kosong menghapus status tersebut. Bahasa Inggris menjadi cadangan. Tidak mengganti status sebenarnya.
enobjectopsional
deobjectopsional
esobjectopsional
pt-BRobjectopsional
itobjectopsional
ruobjectopsional
zh-CNobjectopsional
frobjectopsional
koobjectopsional
support_urlstringopsionalURL HTTPS hingga 2,048 karakter, tanpa kredensial. Kosong menghapus. Tautan terbuka di jendela baru.
terms_urlstringopsionalURL HTTPS hingga 2,048 karakter, tanpa kredensial. Kosong menghapus. Tautan terbuka di jendela baru.
privacy_urlstringopsionalURL HTTPS hingga 2,048 karakter, tanpa kredensial. Kosong menghapus. Tautan terbuka di jendela baru.
return_button_textstringopsionalLabel hingga 60 karakter. Gunakan redirect_url/cancel_url/redirect_automatically/language tingkat atas untuk perilaku faktur.
show_return_buttonbooleanopsionalTampilkan tombol manual Kembali ke merchant/batal di checkout, termasuk status akhir. Jangan sertakan untuk mewarisi tampilan toko (bawaan true); false menyembunyikannya. Tidak membatalkan faktur, menyembunyikan URL dalam JSON, atau menonaktifkan pengalihan sukses otomatis. Tetapkan redirect_automatically tingkat atas ke false secara terpisah jika diperlukan. Memerlukan merchant 8.1.4 atau yang lebih baru.Detail
Tampilkan tombol manual Kembali ke merchant/batal di checkout, termasuk status akhir. Jangan sertakan untuk mewarisi tampilan toko (bawaan true); false menyembunyikannya. Tidak membatalkan faktur, menyembunyikan URL dalam JSON, atau menonaktifkan pengalihan sukses otomatis. Tetapkan redirect_automatically tingkat atas ke false secara terpisah jika diperlukan. Memerlukan merchant 8.1.4 atau yang lebih baru.
metadataobject | nullopsional
Objek JSON khusus merchant; tidak disertakan atau null menjadi {}, maksimum 4,096 byte terenkode dan lima tingkat penyarangan. firstname, lastname, street, street2, zip, city, country, countryiso2, company, dan vatid divalidasi, dinormalisasi, dan diproyeksikan ke kolom ringkasan pelanggan.Detail
Objek JSON khusus merchant; tidak disertakan atau null menjadi {}, maksimum 4,096 byte terenkode dan lima tingkat penyarangan. firstname, lastname, street, street2, zip, city, country, countryiso2, company, dan vatid divalidasi, dinormalisasi, dan diproyeksikan ke kolom ringkasan pelanggan.
Respons 201 new invoice; 200 exact idempotent replay
Contoh respons
{
"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"
}
}Kolom respons
dataobject
emailstring | nullselaluEmail pelanggan khusus merchant. Tidak pernah dikembalikan oleh checkout publik.
customer_namestring | nullselaluNama tampilan yang diturunkan dari metadata pribadi firstname, lastname, dan company.
customer_addressstring | nullselaluAlamat satu baris untuk merchant yang diturunkan dari metadata pribadi company, street, street2, zip, city, country, countryiso2, dan vatid.
exchange_rate_spread_percentdecimal stringselaluSpread kuotasi terkunci: pengesampingan saat pembuatan, atau pengaturan bawaan toko jika tidak disertakan. Diterapkan sebelum pembulatan ke atas; tidak pernah berubah pada faktur ini.
underpayment_tolerance_percentdecimal stringselaluPersentase kekurangan yang diterima dan tidak dapat diubah, disimpan dalam snapshot saat faktur dibuat.
amount_statusamount statusselalunone, partial, paid, atau overpaid. Faktur bernilai nol yang secara eksplisit diizinkan diselesaikan dengan none dan tanpa metode pembayaran.
winning_payment_intent_idUUID | nullselaluMetode pembayaran yang menyelesaikan faktur, saat dipilih.
monitoring_expires_atRFC 3339 timestampselaluBatas akhir pemantauan terlambat paling akhir yang dikonfigurasi di antara metode pembayaran.
ipn_urlstring | nullselaluTujuan IPN efektif per faktur. Hanya respons merchant; dihilangkan dari checkout publik.
cancel_urlstring | nullselaluURL kembali efektif yang digunakan saat checkout berakhir tanpa pembayaran berhasil.
redirect_automaticallybooleanselaluApakah checkout harus mengalihkan secara otomatis setelah berhasil.
metadataobjectselalu
Metadata merchant. Tidak pernah dikembalikan oleh checkout publik. Alat pembayaran konsol menambahkan asal payment_tool (id, kind, title, pricing, requested_amount, request_id); ini tidak membuktikan pembayaran. Autentikasi callback dan penuhi invoice.settled satu kali per invoice_id.Detail
Metadata merchant. Tidak pernah dikembalikan oleh checkout publik. Alat pembayaran konsol menambahkan asal payment_tool (id, kind, title, pricing, requested_amount, request_id); ini tidak membuktikan pembayaran. Autentikasi callback dan penuhi invoice.settled satu kali per invoice_id.
payment_intents[]object[]selalu
Metode pembayaran yang diberi kuotasi dan status pemantauan.
payment_railonchain | lightningselaluTransport faktur. Bitcoin on-chain dan Lightning bisa berbagi asset_id; gunakan id intent beserta kolom ini, bukan simbol saja. Ini berbeda dari payment_rail pemindai dalam katalog aset.Detail
Transport faktur. Bitcoin on-chain dan Lightning bisa berbagi asset_id; gunakan id intent beserta kolom ini, bukan simbol saja. Ini berbeda dari payment_rail pemindai dalam katalog aset.
bolt11string | nullselaluPermintaan pembayaran Lightning, jika tidak null. Bayar permintaan ini dengan dompet Lightning; jangan pernah mengirim dana on-chain ke hash pembayarannya.
networkstringselaluJaringan yang dikonfigurasi, saat ini mainnet untuk aset pembayaran yang didukung.
asset_decimalsintegerselaluPresisi unit atomik. BTC Lightning menggunakan 11 (millisatoshi), bukan 8 seperti Bitcoin on-chain. Kuotasi berupa satoshi utuh; penerimaan mempertahankan presisi millisatoshi.
quote_ratedecimal stringselaluUnit aset per satu unit mata uang faktur, termasuk spread terkunci. Contohnya 1.02 USDC per USD. Bukan kurs kebalikannya.
quote_detailsobject | nullselaluAsal kuotasi terkunci: reference_rate sebelum spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at, dan asset_fetched_at. Null pada faktur lama; tidak ada nilai historis yang direkayasa.Detail
Asal kuotasi terkunci: reference_rate sebelum spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at, dan asset_fetched_at. Null pada faktur lama; tidak ada nilai historis yang direkayasa.
expected_amountdecimal stringselaluJumlah aset terkunci yang presisi untuk dibayar setelah spread dan pembulatan ke atas. Mulai 4.1.1, stablecoin fiat terverifikasi yang dikenali (seperti USDC, USDT, DAI, USDS, EURC) dibulatkan ke atas hingga paling banyak dua desimal; 1.321 menjadi 1.33, tidak pernah 1.32. Ini jumlah yang diharapkan bahkan dengan toleransi nol. Aset lain mempertahankan presisi adaptif. Harga faktur yang sudah ada tidak pernah dihitung ulang.Detail
Jumlah aset terkunci yang presisi untuk dibayar setelah spread dan pembulatan ke atas. Mulai 4.1.1, stablecoin fiat terverifikasi yang dikenali (seperti USDC, USDT, DAI, USDS, EURC) dibulatkan ke atas hingga paling banyak dua desimal; 1.321 menjadi 1.33, tidak pernah 1.32. Ini jumlah yang diharapkan bahkan dengan toleransi nol. Aset lain mempertahankan presisi adaptif. Harga faktur yang sudah ada tidak pernah dihitung ulang.
minimum_payment_amountdecimal stringselaluJumlah terkecil yang diterima sebagai lunas setelah menerapkan toleransi faktur.
minimum_payment_amount_atomicinteger stringselaluAmbang diterima yang presisi dalam unit terkecil aset.
destination_addressstringselaluAlamat penerimaan on-chain, atau hash pembayaran 64 karakter untuk Lightning. Gunakan bolt11 untuk membayar Lightning; hash-nya bukan alamat Bitcoin.
destination_tagstring | nullselaluReferensi pembayaran publik wajib jika jalur menggunakannya: destination tag XRP, ID memo Stellar, atau komentar faktur TON. Null untuk jalur dengan alamat unik.
Catatan penggunaan
- payment_methods memfilter metode toko aktif hanya untuk faktur ini. Tidak disertakan/null mempertahankan semua metode toko; [] tidak valid. Temukan petunjuk kecil chain_slug dan ticker aset yang ditampilkan di Proyek → Toko → Metode pembayaran. Daftar payment-assets API menyediakan chain_slug, asset.symbol, dan asset.id. Gunakan {chain_slug: ethereum, asset_tickers: [USDC, USDT]} untuk token Ethereum yang diterima; BTC dan PEPE bekerja dengan cara yang sama pada blockchain pilihan masing-masing. Ticker tidak peka huruf besar-kecil, dibatasi ke blockchain, dan hanya dicocokkan di dalam toko. Dua kontrak diterima dengan ticker yang sama mengembalikan 400 alih-alih memilih salah satunya, bahkan jika salah satunya belum siap; gunakan asset_ids untuk kasus tersebut. Aset native, token katalog, dan token kustom mengikuti aturan yang sama. Setiap blockchain/jalur boleh muncul sekali; paling banyak 64 metode akhir. Merchant 5.4.0+: pilihan tidak dikenal, nonaktif, salah blockchain, atau tidak diterima diabaikan. Jika seluruh pilihan tidak memiliki kecocokan aktif yang diterima, pengaturan bawaan toko berlaku; jika ada, hanya pilihan cocok yang digunakan. Entri blockchain saja mencakup setiap aset on-chain aktif yang diterima. Metode aktif terpilih memerlukan dompet valid, adapter pemindai terinstal, dan kurs tepercaya. Mulai 6.0.6, pemindai tidak tersedia, masa tunggu, dan pemeriksaan kesehatan tertunda/usang tidak memblokir pembuatan faktur atau menghapus metode on-chain yang dikonfigurasi. Deteksi mencoba ulang otomatis; penyelesaian tetap memerlukan kuorum penyedia dan konfirmasi. Pantau receive_readiness dan jaga penyedia tetap tersedia: faktur bisa tetap belum terverifikasi sampai pemindai pulih. Alokasi subalamat Monero dan pembuatan BOLT11 Lightning tetap memerlukan layanan dompet/node eksternalnya. Kegagalan mengembalikan error.message beserta error.details.payment_methods dengan chain_slug, asset_ticker, reason_code, dan, untuk diagnosis pemindai, required_endpoint_role, healthy_endpoints, serta required_independent_providers. TRON menerima riwayat terindeks atau API blok native tersolidifikasi mentah yang didukung; kesehatan dasar saja tidak membuktikan kompatibilitas pemindai. Kegagalan harga mengidentifikasi aset/mata uang. Tidak ada yang mengaktifkan aset tidak diterima atau mengubah kebijakan toko. Pada versi merchant sebelum 5.4.0, pilihan eksplisit tidak dikenal/nonaktif justru gagal. Metode faktur yang ada tidak pernah meluas saat pengaturan toko berubah. Lightning harus dipilih secara terpisah. Replay mempertahankan metode asli, dan mengubah pilihan dengan Idempotency-Key yang sama mengembalikan 409.
- checkout_appearance mendukung setiap pengaturan tampilan yang tercantum di atas. Kolom yang tidak disertakan mewarisi, array mengganti, dan kolom pesan bersarang digabungkan; objek pesan kosong menghapus cakupan tersebut. Desain dan gambar hasilnya disimpan untuk faktur ini tanpa mengedit toko. Baca appearance dari JSON checkout publik untuk memeriksa hasilnya. Seluruh permintaan dibatasi 32 KiB dan pengaturan hasilnya 20 KiB.
- Mengubah checkout_appearance dengan Idempotency-Key yang sama mengembalikan 409; coba ulang dengan byte mentah identik. Tampilan tidak mengubah jumlah, kurs, aset yang diterima, persyaratan konfirmasi, status sebenarnya, atau izin penyematan. Tanpa HTML, CSS, skrip, atau pengambilan gambar jarak jauh.
- exchange_rate_spread_percent menggantikan pengaturan bawaan toko untuk faktur ini: jangan sertakan atau kirim null untuk mewarisi, atau kirim "0" untuk menonaktifkan. Kuotasi faktur yang ada tidak pernah berubah.
- Spread diterapkan sebelum pembulatan ke atas. Biaya tetap berdasarkan jumlah fiat faktur asli, tidak termasuk spread.
- Selalu kirim expected_amount atau expected_amount_atomic yang dikembalikan. Pembulatan ke atas, dibatasi presisi aset, 0.1% dari jumlah, dan satu unit minor fiat.
- Percobaan ulang harus mempertahankan kredensial, Idempotency-Key, dan byte body persis yang sama. Mengubah spread dengan kunci yang sama mengembalikan 409 idempotency_conflict.
- Replay persis diperiksa sebelum kuotasi baru, DNS callback, atau penyiapan alamat. Cakupan kredensial dan otorisasi proyek/toko tetap diperiksa pada setiap permintaan.
- ipn_url efektif memerlukan rahasia penandatanganan IPN toko. Kolom body tidak dikenal ditolak.
Kesalahan
GETDaftar faktur/v1/projects/{project_id}/invoicesHanya baca
Mengembalikan halaman ringkas ringkasan faktur dalam cakupan, diurutkan dari terbaru, termasuk email khusus merchant dan kolom pelanggan yang diturunkan dari metadata yang dikenali. Filter pencarian, status, dan toko dievaluasi di sisi server; respons menyertakan total dan has_more untuk paginasi yang terprediksi.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | direkomendasikan | application/json |
Parameter path
Parameter kueri
searchstringAwalan invoice-id, order-id, atau email opsional yang tidak peka huruf besar-kecil; UUID faktur persis; atau substring di seluruh deskripsi dan kolom pelanggan yang dikenali. Semua kunci metadata dan nilai teks, angka, serta boolean (termasuk objek/array bersarang) juga mendukung pencarian awalan kata terindeks: setiap kata pencarian harus cocok, tanda baca dianggap pemisah. Spasi tepi dipangkas, paling banyak 100 karakter, tanpa karakter kontrol. Kecocokan metadata tidak menambahkan metadata mentah ke respons daftar; gunakan detail faktur untuk membacanya.Detail
Awalan invoice-id, order-id, atau email opsional yang tidak peka huruf besar-kecil; UUID faktur persis; atau substring di seluruh deskripsi dan kolom pelanggan yang dikenali. Semua kunci metadata dan nilai teks, angka, serta boolean (termasuk objek/array bersarang) juga mendukung pencarian awalan kata terindeks: setiap kata pencarian harus cocok, tanda baca dianggap pemisah. Spasi tepi dipangkas, paling banyak 100 karakter, tanpa karakter kontrol. Kecocokan metadata tidak menambahkan metadata mentah ke respons daftar; gunakan detail faktur untuk membacanya.
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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
}
}Kolom respons
data[]object[]
emailstring | nullselaluEmail pelanggan khusus merchant. Tidak pernah dikembalikan oleh checkout publik.
customer_namestring | nullselaluNama tampilan yang diturunkan dari metadata pribadi firstname, lastname, dan company.
customer_addressstring | nullselaluAlamat satu baris untuk merchant yang diturunkan dari metadata pribadi company, street, street2, zip, city, country, countryiso2, dan vatid.
exchange_rate_spread_percentdecimal stringselaluSpread kuotasi terkunci: pengesampingan saat pembuatan, atau pengaturan bawaan toko jika tidak disertakan. Diterapkan sebelum pembulatan ke atas; tidak pernah berubah pada faktur ini.
underpayment_tolerance_percentdecimal stringselaluPersentase kekurangan yang diterima dan tidak dapat diubah, disimpan dalam snapshot saat faktur dibuat.
amount_statusamount statusselalunone, partial, paid, atau overpaid. Faktur bernilai nol yang secara eksplisit diizinkan diselesaikan dengan none dan tanpa metode pembayaran.
winning_payment_intent_idUUID | nullselaluMetode pembayaran yang menyelesaikan faktur, saat dipilih.
monitoring_expires_atRFC 3339 timestampselaluBatas akhir pemantauan terlambat paling akhir yang dikonfigurasi di antara metode pembayaran.
paginationobject
totalintegerselaluTotal baris yang cocok dengan filter proyek, toko, status, dan pencarian dalam snapshot halaman.
has_morebooleanselaluTrue jika offset ditambah jumlah baris yang dikembalikan lebih kecil dari total.
Catatan penggunaan
- Diurutkan berdasarkan created_at menurun, lalu id internal menurun.
- Item daftar adalah objek InvoiceSummary; email, customer_name, dan customer_address khusus merchant. Panggil detail untuk metadata mentah dan intent pembayaran.
- Untuk halaman berikutnya, tetapkan offset ke pagination.offset + pagination.limit hanya jika has_more true.
- Hitungan dan halaman dibaca dari satu snapshot database repeatable-read; penulisan bersamaan muncul pada permintaan berikutnya.
Kesalahan
GETAmbil faktur/v1/projects/{project_id}/invoices/{invoice_id}Hanya baca
Mengembalikan detail faktur merchant lengkap dan URL checkout aktif saat ini. Gunakan rute ini untuk polling dan rekonsiliasi.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | direkomendasikan | application/json |
Parameter path
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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"
}
}Kolom respons
dataobject
emailstring | nullselaluEmail pelanggan khusus merchant. Tidak pernah dikembalikan oleh checkout publik.
customer_namestring | nullselaluNama tampilan yang diturunkan dari metadata pribadi firstname, lastname, dan company.
customer_addressstring | nullselaluAlamat satu baris untuk merchant yang diturunkan dari metadata pribadi company, street, street2, zip, city, country, countryiso2, dan vatid.
exchange_rate_spread_percentdecimal stringselaluSpread kuotasi terkunci: pengesampingan saat pembuatan, atau pengaturan bawaan toko jika tidak disertakan. Diterapkan sebelum pembulatan ke atas; tidak pernah berubah pada faktur ini.
underpayment_tolerance_percentdecimal stringselaluPersentase kekurangan yang diterima dan tidak dapat diubah, disimpan dalam snapshot saat faktur dibuat.
amount_statusamount statusselalunone, partial, paid, atau overpaid. Faktur bernilai nol yang secara eksplisit diizinkan diselesaikan dengan none dan tanpa metode pembayaran.
winning_payment_intent_idUUID | nullselaluMetode pembayaran yang menyelesaikan faktur, saat dipilih.
monitoring_expires_atRFC 3339 timestampselaluBatas akhir pemantauan terlambat paling akhir yang dikonfigurasi di antara metode pembayaran.
ipn_urlstring | nullselaluTujuan IPN efektif per faktur. Hanya respons merchant; dihilangkan dari checkout publik.
cancel_urlstring | nullselaluURL kembali efektif yang digunakan saat checkout berakhir tanpa pembayaran berhasil.
redirect_automaticallybooleanselaluApakah checkout harus mengalihkan secara otomatis setelah berhasil.
metadataobjectselalu
Metadata merchant. Tidak pernah dikembalikan oleh checkout publik. Alat pembayaran konsol menambahkan asal payment_tool (id, kind, title, pricing, requested_amount, request_id); ini tidak membuktikan pembayaran. Autentikasi callback dan penuhi invoice.settled satu kali per invoice_id.Detail
Metadata merchant. Tidak pernah dikembalikan oleh checkout publik. Alat pembayaran konsol menambahkan asal payment_tool (id, kind, title, pricing, requested_amount, request_id); ini tidak membuktikan pembayaran. Autentikasi callback dan penuhi invoice.settled satu kali per invoice_id.
payment_intents[]object[]selalu
Metode pembayaran yang diberi kuotasi dan status pemantauan.
payment_railonchain | lightningselaluTransport faktur. Bitcoin on-chain dan Lightning bisa berbagi asset_id; gunakan id intent beserta kolom ini, bukan simbol saja. Ini berbeda dari payment_rail pemindai dalam katalog aset.Detail
Transport faktur. Bitcoin on-chain dan Lightning bisa berbagi asset_id; gunakan id intent beserta kolom ini, bukan simbol saja. Ini berbeda dari payment_rail pemindai dalam katalog aset.
bolt11string | nullselaluPermintaan pembayaran Lightning, jika tidak null. Bayar permintaan ini dengan dompet Lightning; jangan pernah mengirim dana on-chain ke hash pembayarannya.
networkstringselaluJaringan yang dikonfigurasi, saat ini mainnet untuk aset pembayaran yang didukung.
asset_decimalsintegerselaluPresisi unit atomik. BTC Lightning menggunakan 11 (millisatoshi), bukan 8 seperti Bitcoin on-chain. Kuotasi berupa satoshi utuh; penerimaan mempertahankan presisi millisatoshi.
quote_ratedecimal stringselaluUnit aset per satu unit mata uang faktur, termasuk spread terkunci. Contohnya 1.02 USDC per USD. Bukan kurs kebalikannya.
quote_detailsobject | nullselaluAsal kuotasi terkunci: reference_rate sebelum spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at, dan asset_fetched_at. Null pada faktur lama; tidak ada nilai historis yang direkayasa.Detail
Asal kuotasi terkunci: reference_rate sebelum spread, unrounded_payment_amount, rounding_adjustment, pricing_provider, asset_provider, pricing_fetched_at, dan asset_fetched_at. Null pada faktur lama; tidak ada nilai historis yang direkayasa.
expected_amountdecimal stringselaluJumlah aset terkunci yang presisi untuk dibayar setelah spread dan pembulatan ke atas. Mulai 4.1.1, stablecoin fiat terverifikasi yang dikenali (seperti USDC, USDT, DAI, USDS, EURC) dibulatkan ke atas hingga paling banyak dua desimal; 1.321 menjadi 1.33, tidak pernah 1.32. Ini jumlah yang diharapkan bahkan dengan toleransi nol. Aset lain mempertahankan presisi adaptif. Harga faktur yang sudah ada tidak pernah dihitung ulang.Detail
Jumlah aset terkunci yang presisi untuk dibayar setelah spread dan pembulatan ke atas. Mulai 4.1.1, stablecoin fiat terverifikasi yang dikenali (seperti USDC, USDT, DAI, USDS, EURC) dibulatkan ke atas hingga paling banyak dua desimal; 1.321 menjadi 1.33, tidak pernah 1.32. Ini jumlah yang diharapkan bahkan dengan toleransi nol. Aset lain mempertahankan presisi adaptif. Harga faktur yang sudah ada tidak pernah dihitung ulang.
minimum_payment_amountdecimal stringselaluJumlah terkecil yang diterima sebagai lunas setelah menerapkan toleransi faktur.
minimum_payment_amount_atomicinteger stringselaluAmbang diterima yang presisi dalam unit terkecil aset.
destination_addressstringselaluAlamat penerimaan on-chain, atau hash pembayaran 64 karakter untuk Lightning. Gunakan bolt11 untuk membayar Lightning; hash-nya bukan alamat Bitcoin.
destination_tagstring | nullselaluReferensi pembayaran publik wajib jika jalur menggunakannya: destination tag XRP, ID memo Stellar, atau komentar faktur TON. Null untuk jalur dengan alamat unik.
Catatan penggunaan
- Pencarian dalam cakupan sengaja mengembalikan invoice_not_found jika ID publik tidak ada dalam proyek yang diotorisasi.
- links.checkout menggunakan Toko → Dasar → Domain toko: nama host pay aktif toko ini, lalu pilihan toko bawaannya, lalu domain utama sistem. Host yang dihentikan/draf atau salah layanan diabaikan. Ini juga berlaku untuk respons pembuatan dan MCP; tautan ditentukan saat respons, termasuk replay idempoten. Tautan callback bertanda tangan dibekukan saat peristiwa dibuat, tidak ditulis ulang pada percobaan ulang. Preferensi ini hanya menghasilkan tautan; tidak mengalihkan trafik atau mengubah pembatasan IP.
Kesalahan
GETDaftar pembayaran faktur/v1/projects/{project_id}/invoices/{invoice_id}/paymentsHanya baca
Riwayat transfer terkini lengkap, termasuk observasi yang dibatalkan validitasnya. Gunakan saat callback menandai payments_truncated. Ini status terkini, bukan rekonstruksi peristiwa lama.
Autentikasi & header
| Header | Kehadiran | Aturan |
|---|---|---|
| Authorization | wajib | Bearer YOUR_MERCHANT_API_TOKEN |
| Accept | direkomendasikan | application/json |
Parameter path
Parameter kueri
Permintaan
: "${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))Respons 200 application/json
Contoh respons
{
"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}
}Kolom respons
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_urlstringCatatan penggunaan
- Observasi adalah log token, output UTXO, atau transfer jalur lain, belum tentu hash transaksi unik. Deduplikasi berdasarkan payment_id; transaction_id ditambah event_index mengidentifikasi transfer blockchain.
- status adalah detected, confirming, final, reorged, replaced, atau invalid. Hanya observasi counts_towards_received yang berkontribusi pada jumlah diterima. Jangan pernah menjumlahkan jumlah lintas aset berbeda.
- Catatan Lightning menggunakan payment_hash dengan transaction_id, konfirmasi, dan tautan penjelajah null; presisi BTC 11 (millisatoshi). Tidak ada preimage, BOLT11, atau rahasia dompet yang ditampilkan.
- Diurutkan berdasarkan observed_at menurun, lalu payment_id menurun. Hitungan dan halaman menggunakan satu snapshot repeatable-read; halaman berikutnya bisa berubah saat pembayaran tiba. Deduplikasi berdasarkan payment_id saat memaginasi faktur aktif.
- Cakupan proyek hanya baca yang ada, pembatasan IP, dan batas permintaan per kredensial berlaku. Jangan pernah mengikuti tautan dari callback dengan tokenmu kecuali origin-nya cocok dengan host API yang kamu konfigurasi.
Kesalahan
GETKerangka checkout/Publik
Root host checkout yang dikelola yang menyajikan aplikasi checkout tanpa memilih faktur. Integrasi pelanggan biasanya sebaiknya menggunakan links.checkout.
Autentikasi & header
Publik
Permintaan
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())Respons 200 text/html
Contoh respons
<!doctype html>
<!-- Hosted Wholly Crypto checkout shell -->Catatan penggunaan
- Token bearer tidak diperlukan.
- Edge checkout yang dikelola mengizinkan GET/HEAD dan menolak metode lain.
Kesalahan
GETHalaman checkout yang dihosting/invoice/{invoice_id}Publik
Checkout HTML untuk pelanggan. Halaman mengambil JSON aman untuk checkout dari host checkout yang sama. Penyematan ditolak kecuali toko mengaktifkannya dan secara eksplisit mengizinkan origin HTTPS induk.
Autentikasi & header
Publik
Parameter path
Permintaan
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())Respons 200 text/html
Contoh respons
<!doctype html>
<!-- Hosted Wholly Crypto checkout application -->Catatan penggunaan
- Token bearer tidak diterima atau diperlukan.
- Kerangka HTML sendiri mengembalikan 200 bahkan saat faktur tidak ada; permintaan JSON checkout-nya kemudian menerima invoice_not_found.
- Respons bersifat no-store, noindex, dan memiliki CSP frame-ancestors khusus faktur.
- Proyek/toko nonaktif atau faktur tidak dikenal tidak menampilkan data checkout.
Kesalahan
GETFaktur yang aman untuk checkout/checkout-api/invoices/{invoice_id}Publik
Hanya mengembalikan kolom yang diperlukan untuk merender checkout. Sengaja menghilangkan ID internal, email pelanggan dan kolom alamat turunan, URL IPN, metadata merchant, ID dompet, path derivasi, serta diagnosis pemantau.
Autentikasi & header
Publik
Parameter path
Permintaan
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))Respons 200 application/json
Contoh respons
{
"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": []
}
]
}
}Kolom respons
dataobject
exchange_rate_spread_percentdecimal stringselaluSpread kuotasi efektif yang dikunci saat pembuatan, termasuk pengesampingan per faktur.
underpayment_tolerance_percentdecimal stringselaluPersentase kekurangan yang diterima untuk faktur ini.
amount_statusamount statusselalunone, partial, paid, atau overpaid. Faktur bernilai nol yang secara eksplisit diizinkan diselesaikan dengan none dan tanpa metode pembayaran.
active_payment_method_idUUID | nullselaluMetode pembayaran tercantum yang telah menerima dana. Checkout tetap pada metode ini agar kekurangan pembayaran tidak dilanjutkan dengan aset yang tidak kompatibel.
server_timeRFC 3339 timestampselaluJam server yang dicatat untuk respons ini; gunakan dengan expires_at untuk menghindari perbedaan jam perangkat pelanggan.
expires_in_secondsintegerselaluSisa detik utuh pada server_time, dibulatkan ke atas dan dibatasi minimum nol.
payment_openbooleanselaluTrue hanya selama faktur new atau processing belum melewati tenggat dan memiliki setidaknya satu metode yang bisa dibayar dengan sisa jumlah.
projectobjectselalu
name, checkout_title, checkout_description, theme, accent_color, dan logo_url.
appearanceobjectselalu
Tampilan efektif: pengesampingan beku per faktur jika diberikan, jika tidak desain toko saat ini. Tidak pernah mengubah kolom keuangan atau peringatan keamanan.
inherit_default_storebooleanselaluTrue jika toko bawaan proyek menyediakan tampilan ini. False untuk toko independen dan pengesampingan faktur beku.
invoice_overridebooleanselaluTrue jika checkout_appearance diberikan saat pembuatan faktur. Tidak disertakan/null mempertahankan false.
titlestringselaluJudul merchant, pesan atas, dan pesan bawah berupa teks biasa. intro menggantikan customer_message; teks lama yang tersimpan dipertahankan. Jangan pernah mengevaluasi sebagai markup.
introstringselaluJudul merchant, pesan atas, dan pesan bawah berupa teks biasa. intro menggantikan customer_message; teks lama yang tersimpan dipertahankan. Jangan pernah mengevaluasi sebagai markup.
outrostringselaluJudul merchant, pesan atas, dan pesan bawah berupa teks biasa. intro menggantikan customer_message; teks lama yang tersimpan dipertahankan. Jangan pernah mengevaluasi sebagai markup.
customer_messagestringselaluAlias kompatibilitas intro yang sudah tidak disarankan. Gunakan intro untuk integrasi baru.
accent_colorstringselaluWarna #RRGGBB ketat. Warna opsional kosong untuk nilai otomatis; kontras latar depan dihitung.
background_colorstringselaluWarna #RRGGBB ketat. Warna opsional kosong untuk nilai otomatis; kontras latar depan dihitung.
card_colorstringselaluWarna #RRGGBB ketat. Warna opsional kosong untuk nilai otomatis; kontras latar depan dihitung.
button_colorstringselaluWarna #RRGGBB ketat. Warna opsional kosong untuk nilai otomatis; kontras latar depan dihitung.
logo_sizestringselalusmall, medium, atau large; left atau center. Gambar dimuat utuh dalam batas, tidak dipotong.
logo_alignmentstringselalusmall, medium, atau large; left atau center. Gambar dimuat utuh dalam batas, tidak dipotong.
imagesobjectselaluURL logo_light, logo_dark, dan favicon opsional: gambar PNG ternormalisasi, dibatasi cakupannya, dan berasal dari origin yang sama.
show_order_idbooleanselaluVisibilitas ID pesanan, deskripsi di bawah judul, dan bentangan awal ID pesanan. Jumlah tetap terlihat; ini kontrol tampilan, bukan penyamaran data.
show_descriptionbooleanselaluVisibilitas ID pesanan, deskripsi di bawah judul, dan bentangan awal ID pesanan. Jumlah tetap terlihat; ini kontrol tampilan, bukan penyamaran data.
details_expandedbooleanselaluVisibilitas ID pesanan, deskripsi di bawah judul, dan bentangan awal ID pesanan. Jumlah tetap terlihat; ini kontrol tampilan, bukan penyamaran data.
show_project_namebooleanselaluMerchant 5.6.0+: visibilitas nama header. Keduanya secara bawaan true. Identitas proyek/toko tetap tersedia dalam JSON.
show_store_namebooleanselaluMerchant 5.6.0+: visibilitas nama header. Keduanya secara bawaan true. Identitas proyek/toko tetap tersedia dalam JSON.
featured_chains[]arrayselaluPreferensi berurutan, diterapkan hanya pada metode yang sudah ada dalam faktur. Metode yang tidak ada atau nonaktif diabaikan.
featured_asset_ids[]arrayselaluPreferensi berurutan, diterapkan hanya pada metode yang sudah ada dalam faktur. Metode yang tidak ada atau nonaktif diabaikan.
default_asset_idUUID | nullselaluMetode awal yang disarankan. Preferensi pelanggan tersimpan yang valid atau metode yang sudah menerima dana diprioritaskan.
messagesobjectselalu
Teks biasa untuk en, de, es, pt-BR, it, ru, zh-CN, fr, ko, dan ja, dengan kunci waiting, confirming, paid, underpaid, dan expired. Bahasa Inggris menjadi cadangan untuk pesan merchant yang belum tersedia. Bersifat tambahan; tidak pernah mengganti status sebenarnya. Konten yang ditulis merchant tidak diterjemahkan otomatis.Detail
Teks biasa untuk en, de, es, pt-BR, it, ru, zh-CN, fr, ko, dan ja, dengan kunci waiting, confirming, paid, underpaid, dan expired. Bahasa Inggris menjadi cadangan untuk pesan merchant yang belum tersedia. Bersifat tambahan; tidak pernah mengganti status sebenarnya. Konten yang ditulis merchant tidak diterjemahkan otomatis.
support_emailstringselaluKontak dan tautan HTTPS opsional, tanpa kredensial URL. Tautan eksternal terbuka di jendela baru.
support_urlstringselaluKontak dan tautan HTTPS opsional, tanpa kredensial URL. Tautan eksternal terbuka di jendela baru.
terms_urlstringselaluKontak dan tautan HTTPS opsional, tanpa kredensial URL. Tautan eksternal terbuka di jendela baru.
privacy_urlstringselaluKontak dan tautan HTTPS opsional, tanpa kredensial URL. Tautan eksternal terbuka di jendela baru.
return_button_textstringselaluHanya label opsional. Tujuan sukses/batal dan kebijakan pengalihan tetap milik faktur.
show_return_buttonbooleanselaluVisibilitas tombol kembali/batal manual; bawaan true. Berlaku pada status aktif dan akhir, bukan pengalihan sukses otomatis. Tersedia mulai merchant 8.1.4.
payment_methods[]object[]selalu
Metode pembayaran yang aman untuk checkout.
payment_railonchain | lightningselaluLightning tetap menjadi metode Bitcoin, terpisah dari BTC on-chain. Identifikasi pilihan berdasarkan id intent dan jalur, bukan asset_id saja.
bolt11string | nullselaluPermintaan Lightning bertanda tangan; null untuk metode on-chain. Jangan pernah membayar setelah payable menjadi false.
payment_hashstring | nullselaluHash pembayaran Lightning untuk rekonsiliasi, bukan alamat penerimaan. Null untuk metode on-chain.
asset_idUUIDselaluUUID aset yang digunakan preferensi tampilan; berbeda dari id intent pembayaran faktur ini.
caip_network_idstringselaluIdentitas jaringan kanonis yang digunakan untuk membedakan blockchain terpilih secara jelas.
caip_asset_idstring | nullselaluIdentitas aset kanonis yang persis, termasuk kontrak token atau mint terverifikasi jika berlaku.
asset_icon_urlstring | nullselaluIkon aset dalam cache lokal dari origin yang sama, atau null jika tidak ada pemetaan CoinGecko terverifikasi.
contract_addressstring | nullselaluKontrak ERC-20 kanonis atau mint SPL untuk token; null untuk mata uang native.
token_standarderc20 | spl-token | nullselaluRuntime token terverifikasi, atau null untuk mata uang native.
asset_decimalsintegerselaluPresisi unit atomik: 11 untuk millisatoshi BTC Lightning, 8 untuk satoshi BTC on-chain.
payablebooleanselaluTrue hanya jika metode persis ini saat ini bisa menerima pembayaran; false untuk metode nonaktif setelah aset lain menerima dana.
expected_amountdecimalselaluKuotasi terkunci penuh dalam unit tampilan dan on-chain sebenarnya. Stablecoin fiat yang dikenali menggunakan paling banyak dua desimal kuotasi, selalu dibulatkan ke atas setelah spread; aset lain menggunakan presisi adaptif. Desimal token sebenarnya, dana diterima, dan sisa pembayaran parsial tetap presisi. Gunakan jumlah yang dikembalikan tanpa perubahan.Detail
Kuotasi terkunci penuh dalam unit tampilan dan on-chain sebenarnya. Stablecoin fiat yang dikenali menggunakan paling banyak dua desimal kuotasi, selalu dibulatkan ke atas setelah spread; aset lain menggunakan presisi adaptif. Desimal token sebenarnya, dana diterima, dan sisa pembayaran parsial tetap presisi. Gunakan jumlah yang dikembalikan tanpa perubahan.
expected_amount_atomicinteger stringselaluKuotasi terkunci penuh dalam unit tampilan dan on-chain sebenarnya. Stablecoin fiat yang dikenali menggunakan paling banyak dua desimal kuotasi, selalu dibulatkan ke atas setelah spread; aset lain menggunakan presisi adaptif. Desimal token sebenarnya, dana diterima, dan sisa pembayaran parsial tetap presisi. Gunakan jumlah yang dikembalikan tanpa perubahan.Detail
Kuotasi terkunci penuh dalam unit tampilan dan on-chain sebenarnya. Stablecoin fiat yang dikenali menggunakan paling banyak dua desimal kuotasi, selalu dibulatkan ke atas setelah spread; aset lain menggunakan presisi adaptif. Desimal token sebenarnya, dana diterima, dan sisa pembayaran parsial tetap presisi. Gunakan jumlah yang dikembalikan tanpa perubahan.
minimum_payment_amountdecimalselaluAmbang penyelesaian yang diterima setelah menerapkan toleransi kekurangan pembayaran.
minimum_payment_amount_atomicinteger stringselaluAmbang penyelesaian yang diterima setelah menerapkan toleransi kekurangan pembayaran.
remaining_amountdecimal stringselaluJumlah tampilan presisi yang masih diperlukan untuk mencapai ambang diterima, dibatasi minimum nol.
remaining_amount_atomicinteger stringselaluKekurangan menuju ambang diterima dalam unit atomik. Ini bukan jumlah pembayaran yang diminta: toleransi hanya memengaruhi penerimaan.
destination_addressstringselaluTujuan on-chain dan referensi opsional. Untuk Lightning, ini hash pembayaran tanpa tag; bayar bolt11/payment_uri sebagai gantinya.
destination_tagstring|nullselaluTujuan on-chain dan referensi opsional. Untuk Lightning, ini hash pembayaran tanpa tag; bayar bolt11/payment_uri sebagai gantinya.
payment_uristring | nullselaluPermintaan sesuai blockchain: ERC-681, Solana Pay, URI native, atau lightning:<bolt11>. Permintaan yang memuat jumlah menggunakan jumlah penuh yang diharapkan dikurangi dana diterima, tidak pernah ambang toleransi. Null jika payable false, termasuk setelah kekurangan yang ditoleransi diterima. QR Lightning mengodekan permintaan Lightning penuh, bukan hash pembayaran.Detail
Permintaan sesuai blockchain: ERC-681, Solana Pay, URI native, atau lightning:<bolt11>. Permintaan yang memuat jumlah menggunakan jumlah penuh yang diharapkan dikurangi dana diterima, tidak pernah ambang toleransi. Null jika payable false, termasuk setelah kekurangan yang ditoleransi diterima. QR Lightning mengodekan permintaan Lightning penuh, bukan hash pembayaran.
qr_urlpath | nullselaluPath QR SVG dari origin yang sama, dengan revisi berdasarkan sequence dan sisa presisi, atau null jika payable false. SVG bersifat no-store.
transaction_countintegerselaluTotal transaksi publik valid yang berbeda yang teramati untuk metode ini.
transactions_truncatedbooleanselaluTrue jika transaction_count melebihi daftar transaksi terbaru yang dikembalikan.
transactions[]object[]selalu
Hingga 10 transaksi publik valid terbaru. Total diterima yang presisi tetap independen dari batas tampilan ini.
Catatan penggunaan
- Token bearer tidak diperlukan.
- Cache-Control adalah no-store dan pengindeksan pencarian dinonaktifkan.
- Perlakukan invoice_id sebagai data yang memberikan akses kepada pelanggan; hindari memublikasikannya tanpa perlu.
- asset_icon_url adalah aset lokal dari origin yang sama; checkout pelanggan tidak perlu menghubungi CoinGecko untuk merendernya.
- Jika destination_tag bukan null, tampilkan dan salin di samping alamat: ini destination tag XRP, ID memo Stellar, atau komentar faktur TON yang wajib dan harus dikirim persis.
- Untuk token terverifikasi, asset_kind adalah token, contract_address mengidentifikasi kontrak ERC-20 atau mint SPL persis, token_standard mengidentifikasi jalur, dan payment_uri memuat identitas token tersebut.
Kesalahan
GETPratinjau checkout toko/invoice/preview/{project_id}Publik
Merender tampilan toko tersimpan dengan jumlah ilustratif dan metadata aset diterima yang nyata. Beralih antara contoh waiting, confirming, paid, underpaid, dan expired tanpa membuat pembayaran.
Autentikasi & header
Publik
Parameter path
Parameter kueri
Permintaan
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())Respons 200 text/html
Contoh respons
<!doctype html>
<!-- Hosted branding preview; no invoice is created -->Catatan penggunaan
- Pratinjau hanya untuk tampilan merek dan tidak boleh dikirim ke pelanggan sebagai permintaan pembayaran.
- Tanpa alamat penerimaan, QR yang bisa dibayar, tindakan dompet, pengalihan, atau polling pembayaran. Contoh tidak mengubah status faktur sebenarnya.
- Respons bersifat no-store, noindex, dan tidak bisa disematkan.
Kesalahan
GETData pratinjau checkout/checkout-api/previews/{project_id}Publik
Mengembalikan tampilan toko efektif dan metadata aset diterima yang aman. payment_methods tetap kosong; preview_methods tidak berisi alamat pembayaran, kuotasi, atau data dompet pribadi.
Autentikasi & header
Publik
Parameter path
Parameter kueri
store_idUUID,opsionalHarus milik proyek ini; ID yang tidak cocok mengembalikan 404. Kolom kueri tidak dikenal ditolak.
Permintaan
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))Respons 200 application/json
Contoh respons
{
"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": []
}
}Kolom respons
dataobject
previewbooleaninvoice_idstringamountstringcurrencystringprojectobject
appearanceobject
inherit_default_storebooleanselaluTrue jika toko bawaan proyek menyediakan tampilan ini. False untuk toko independen dan pengesampingan faktur beku.
invoice_overridebooleanselaluTrue jika checkout_appearance diberikan saat pembuatan faktur. Tidak disertakan/null mempertahankan false.
titlestringselaluJudul merchant, pesan atas, dan pesan bawah berupa teks biasa. intro menggantikan customer_message; teks lama yang tersimpan dipertahankan. Jangan pernah mengevaluasi sebagai markup.
introstringselaluJudul merchant, pesan atas, dan pesan bawah berupa teks biasa. intro menggantikan customer_message; teks lama yang tersimpan dipertahankan. Jangan pernah mengevaluasi sebagai markup.
outrostringselaluJudul merchant, pesan atas, dan pesan bawah berupa teks biasa. intro menggantikan customer_message; teks lama yang tersimpan dipertahankan. Jangan pernah mengevaluasi sebagai markup.
customer_messagestringselaluAlias kompatibilitas intro yang sudah tidak disarankan. Gunakan intro untuk integrasi baru.
accent_colorstringselaluWarna #RRGGBB ketat. Warna opsional kosong untuk nilai otomatis; kontras latar depan dihitung.
background_colorstringselaluWarna #RRGGBB ketat. Warna opsional kosong untuk nilai otomatis; kontras latar depan dihitung.
card_colorstringselaluWarna #RRGGBB ketat. Warna opsional kosong untuk nilai otomatis; kontras latar depan dihitung.
button_colorstringselaluWarna #RRGGBB ketat. Warna opsional kosong untuk nilai otomatis; kontras latar depan dihitung.
logo_sizestringselalusmall, medium, atau large; left atau center. Gambar dimuat utuh dalam batas, tidak dipotong.
logo_alignmentstringselalusmall, medium, atau large; left atau center. Gambar dimuat utuh dalam batas, tidak dipotong.
imagesobjectselaluURL logo_light, logo_dark, dan favicon opsional: gambar PNG ternormalisasi, dibatasi cakupannya, dan berasal dari origin yang sama.
show_order_idbooleanselaluVisibilitas ID pesanan, deskripsi di bawah judul, dan bentangan awal ID pesanan. Jumlah tetap terlihat; ini kontrol tampilan, bukan penyamaran data.
show_descriptionbooleanselaluVisibilitas ID pesanan, deskripsi di bawah judul, dan bentangan awal ID pesanan. Jumlah tetap terlihat; ini kontrol tampilan, bukan penyamaran data.
details_expandedbooleanselaluVisibilitas ID pesanan, deskripsi di bawah judul, dan bentangan awal ID pesanan. Jumlah tetap terlihat; ini kontrol tampilan, bukan penyamaran data.
show_project_namebooleanselaluMerchant 5.6.0+: visibilitas nama header. Keduanya secara bawaan true. Identitas proyek/toko tetap tersedia dalam JSON.
show_store_namebooleanselaluMerchant 5.6.0+: visibilitas nama header. Keduanya secara bawaan true. Identitas proyek/toko tetap tersedia dalam JSON.
featured_chains[]arrayselaluPreferensi berurutan, diterapkan hanya pada metode yang sudah ada dalam faktur. Metode yang tidak ada atau nonaktif diabaikan.
featured_asset_ids[]arrayselaluPreferensi berurutan, diterapkan hanya pada metode yang sudah ada dalam faktur. Metode yang tidak ada atau nonaktif diabaikan.
default_asset_idUUID | nullselaluMetode awal yang disarankan. Preferensi pelanggan tersimpan yang valid atau metode yang sudah menerima dana diprioritaskan.
messagesobjectselalu
Teks biasa untuk en, de, es, pt-BR, it, ru, zh-CN, fr, ko, dan ja, dengan kunci waiting, confirming, paid, underpaid, dan expired. Bahasa Inggris menjadi cadangan untuk pesan merchant yang belum tersedia. Bersifat tambahan; tidak pernah mengganti status sebenarnya. Konten yang ditulis merchant tidak diterjemahkan otomatis.Detail
Teks biasa untuk en, de, es, pt-BR, it, ru, zh-CN, fr, ko, dan ja, dengan kunci waiting, confirming, paid, underpaid, dan expired. Bahasa Inggris menjadi cadangan untuk pesan merchant yang belum tersedia. Bersifat tambahan; tidak pernah mengganti status sebenarnya. Konten yang ditulis merchant tidak diterjemahkan otomatis.
support_emailstringselaluKontak dan tautan HTTPS opsional, tanpa kredensial URL. Tautan eksternal terbuka di jendela baru.
support_urlstringselaluKontak dan tautan HTTPS opsional, tanpa kredensial URL. Tautan eksternal terbuka di jendela baru.
terms_urlstringselaluKontak dan tautan HTTPS opsional, tanpa kredensial URL. Tautan eksternal terbuka di jendela baru.
privacy_urlstringselaluKontak dan tautan HTTPS opsional, tanpa kredensial URL. Tautan eksternal terbuka di jendela baru.
return_button_textstringselaluHanya label opsional. Tujuan sukses/batal dan kebijakan pengalihan tetap milik faktur.
show_return_buttonbooleanselaluVisibilitas tombol kembali/batal manual; bawaan true. Berlaku pada status aktif dan akhir, bukan pengalihan sukses otomatis. Tersedia mulai merchant 8.1.4.
preview_methods[]arraypayment_methods[]arrayCatatan penggunaan
- Token bearer tidak diterima atau diperlukan.
- Tidak ada faktur, tujuan, dompet, transaksi, IPN, webhook, atau metadata merchant yang dikembalikan.
- Gunakan konsol terautentikasi untuk memperoleh tautan pratinjau domain pay yang benar.
Kesalahan
GETGambar checkout toko/checkout-api/invoices/{invoice_id}/appearance-images/{kind}/{revision}/image.pngPublik
Mengembalikan logo toko atau favicon ternormalisasi milik faktur ini. Gunakan URL appearance.images dari data checkout.
Autentikasi & header
Publik
Parameter path
Permintaan
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())Respons 200 image/png
Contoh respons
(binary PNG response)Catatan penggunaan
- Gunakan appearance.images dari JSON checkout. Gambar faktur beku tetap berfungsi setelah toko sumber mengganti atau menghapus unggahan. Revisi yang dihapus secara eksplisit, salah faktur, salah jenis, dan tidak dikenal mengembalikan 404; snapshot tidak pernah beralih ke gambar toko saat ini.
- Tanpa pengesampingan faktur, gambar toko efektif saat ini digunakan dan revisi yang diganti/dihapus mengembalikan 404. Hanya PNG, nosniff, dan caching privat.
- Unggahan gambar toko menerima PNG, JPEG, atau WebP dengan ukuran terbatas dalam konsol terautentikasi; tidak pernah SVG, HTML, atau URL gambar jarak jauh.
Kesalahan
GETGambar pratinjau toko/checkout-api/previews/{project_id}/stores/{store_id}/appearance-images/{kind}/{revision}/image.pngPublik
Mengembalikan gambar pratinjau ternormalisasi hanya untuk proyek, toko, jenis, dan revisi terkini yang cocok.
Autentikasi & header
Publik
Parameter path
Permintaan
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())Respons 200 image/png
Contoh respons
(binary PNG response)Catatan penggunaan
- Gunakan appearance.images dari data pratinjau. ID tidak dikenal atau tidak cocok mengembalikan 404. Tidak ada informasi dompet atau pembayaran yang ditampilkan.
Kesalahan
GETLogo pratinjau dengan revisi/checkout-api/previews/{project_id}/logo/{revision}/image.pngPublik
Mengembalikan logo proyek ternormalisasi hanya jika proyek dan revisi logo yang aman untuk cache cocok. Gunakan project.logo_url dari data pratinjau alih-alih menyusun URL ini.
Autentikasi & header
Publik
Parameter path
Permintaan
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())Respons 200 image/png
Contoh respons
(binary PNG response)Catatan penggunaan
- Proyek tidak dikenal dan revisi logo usang mengembalikan invoice_not_found tanpa mengungkap komponen mana yang tidak ada.
- Gambar dengan revisi yang berhasil diperoleh tidak dapat diubah dan boleh disimpan dalam cache.
Kesalahan
GETGambar QR pembayaran/checkout-api/invoices/{invoice_id}/payment-methods/{intent_id}/qr.svgPublik
Menghasilkan QR SVG 512×512 untuk payload pembayaran yang persis dan sesuai blockchain dari metode pembayaran faktur.
Autentikasi & header
Publik
Parameter path
Permintaan
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())Respons 200 image/svg+xml
Contoh respons
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">…</svg>Catatan penggunaan
- Token bearer tidak diperlukan.
- Gunakan qr_url dengan revisi berdasarkan sequence dan sisa jumlah yang dikembalikan JSON checkout; SVG bersifat private dan no-store.
- Setelah pembayaran parsial, QR meminta sisa jumlah yang presisi dan tetap terkunci pada aset tersebut.
- Mengembalikan 409 setelah kedaluwarsa, selesai, atau saat metode lain aktif; mengembalikan payment_qr_unavailable (422) jika permintaan terlalu besar untuk dienkode.
Kesalahan
GETLogo checkout dengan revisi/checkout-api/invoices/{invoice_id}/logo/{revision}/image.pngPublik
Mengembalikan logo checkout proyek ternormalisasi hanya jika faktur dan revisi logo terkini cocok. Utamakan project.logo_url yang dikembalikan JSON checkout daripada menyusun rute ini.
Autentikasi & header
Publik
Parameter path
Permintaan
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())Respons 200 image/png
Contoh respons
(binary PNG response)Catatan penggunaan
- Token bearer tidak diperlukan.
- Masa cache publik satu tahun dengan immutable karena revisi merupakan status pengalamatan berdasarkan konten.
- Revisi tidak dikenal/tidak cocok mengembalikan invoice_not_found.
Kesalahan
Referensi untuk Wholly Crypto 8.3.2. Untuk versi yang kamu instal, buka Pengaturan → Akses API → Dokumentasi di konsolmu. Lihat rilis.