ping!
Ke aplikasi
Developer · API internal

Pesanan & SMS

Kontrak pembelian nomor, pembacaan SMS, pembatalan, dan penyelesaian order dengan perlindungan idempotensi.

Unduh OpenAPI 3.1
Di halaman ini

Sebelum mengirim request

Semua operasi hanya berlaku untuk order milik sesi. POST sukses memakai HTTP 200. Order yang masih disiapkan dapat berstatus waiting tanpa nomor atau kode. Gunakan flag tindakan server, bukan asumsi dari timer browser.

Kontrak nyata, nilai contoh

Endpoint, field, dan status HTTP mengikuti implementasi. Nilai ID, nomor, OTP, waktu, saldo, serta quote di contoh adalah ilustrasi, bukan data akun atau pilihan yang bisa langsung dibeli. Ganti dengan data dari instalasimu. Halaman ini tidak mengirim request atau menjalankan transaksi.

JavaScript dijalankan pada origin aplikasi setelah login. Contoh cURL memakai PING_ORIGIN dan cookie jar PING_COOKIE_JAR dari panduan autentikasi. Sukses memakai { ok: true, data }; create juga HTTP 200, bukan 201. Semua endpoint di halaman ini memerlukan sesi aktif dan dapat mengembalikan 401, 403, atau 500.

Daftar pesanan

GET/api/ordersSession cookie

Source : app/api/orders/route.ts

Semua order milik pengguna, terbaru lebih dahulu. Tidak ada parameter status, limit, offset, atau cursor. Endpoint daftar tidak melakukan polling provider; gunakan GET detail untuk order terbuka.

GET /api/orders · JavaScript
const response = await fetch("/api/orders", {
  credentials: "same-origin",
  cache: "no-store",
});
const body = await response.json();

if (!response.ok || !body.ok) {
  throw Object.assign(
    new Error(body.error?.message ?? "Request gagal"),
    { code: body.error?.code, status: response.status },
  );
}

const data = body.data;

Buat pesanan

POST/api/ordersSession cookie

Source : app/api/orders/route.ts

Menahan saldo lalu meminta nomor ke provider. HTTP 200 berarti request ditangani, bukan jaminan nomor langsung terbit; periksa status, isPreparing, phone, dan message. Respons memakai Order, bukan activation atau token provider.

Perhatikan sebelum mengirim

Mutasi finansial. Simpan clientRequestId untuk satu niat pembelian sebelum mengirim request. Timeout bukan bukti pembelian gagal. Jangan membuat UUID baru atau melakukan retry otomatis saat hasil belum pasti.

Buat pesanan
Body JSONTipeWajibKeterangan
serviceIdstringYaGunakan Service.id dari GET /api/catalog/services.
countryIdstringYaGunakan Country.id dari GET /api/catalog/countries.
clientRequestIdstring · uuidYaUUID per niat pembelian. Pertahankan UUID yang sama saat recovery request yang sama.
priceOptionIdstringTidakQuote.options[].id. Harus bersama expectedPriceIdr; direkomendasikan agar harga dikonfirmasi.
expectedPriceIdrintegerTidakQuote.options[].price_idr yang disetujui pengguna. Harus bersama priceOptionId.
POST /api/orders · JavaScript
const response = await fetch("/api/orders", {
  method: "POST",
  credentials: "same-origin",
  cache: "no-store",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    "serviceId": "service-example",
    "countryId": "country-example",
    "clientRequestId": "f41c29d8-967d-469d-ae4f-0114c38bf715",
    "priceOptionId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "expectedPriceIdr": 1500
  }),
});
const body = await response.json();

if (!response.ok || !body.ok) {
  throw Object.assign(
    new Error(body.error?.message ?? "Request gagal"),
    { code: body.error?.code, status: response.status },
  );
}

const data = body.data;
Buat pesanan
Kode errorHTTPTindakan
VALIDATION_ERROR400Periksa tipe, field wajib, format UUID, dan field tambahan.
INSUFFICIENT_BALANCE422Tampilkan available dari server dan tawarkan top-up.
PRICE_CHANGED409Ambil quote baru dan minta konfirmasi harga lagi.
PRICE_OPTION_UNAVAILABLE409Ambil quote baru; jangan menebak atau membuat priceOptionId.
PRICE_UNAVAILABLE422Tawarkan pasangan lain atau coba baca quote lagi nanti.
SERVICE_UNAVAILABLE422Muat ulang katalog dan pilih layanan yang tersedia.
COUNTRY_UNAVAILABLE422Muat ulang katalog dan pilih negara yang tersedia.
ACTIVE_ORDER_LIMIT429Selesaikan order yang ada; limit mengikuti pengaturan operator.
ORDER_RATE_LIMIT429Jeda percobaan. Jangan membuat loop POST.
PURCHASE_UNRESOLVED409Jangan membuat pembelian baru. Tunggu rekonsiliasi.
PROVIDER_ERROR502Baca ulang status. Jangan retry pembelian upstream secara otomatis.

Baca pesanan & SMS

GET/api/orders/{id}Session cookie

Source : app/api/orders/[id]/route.ts

Membaca order milik sesi. Untuk order terbuka atau yang memerlukan rekonsiliasi, server dapat memeriksa provider sebelum mengembalikan DTO. Polling UI berjalan setiap 5 detik selama status waiting; status waiting juga mencakup kode yang sudah diterima.

Baca pesanan & SMS
ParameterTipeWajibKeterangan
id (path)stringYaID order milik pengguna bersesi.
GET /api/orders/{id} · JavaScript
const response = await fetch("/api/orders/a4c4b37c-9b68-4b18-bd52-8e0ea3b08d19", {
  credentials: "same-origin",
  cache: "no-store",
});
const body = await response.json();

if (!response.ok || !body.ok) {
  throw Object.assign(
    new Error(body.error?.message ?? "Request gagal"),
    { code: body.error?.code, status: response.status },
  );
}

const data = body.data;
Baca pesanan & SMS
Kode errorHTTPTindakan
NOT_FOUND404Periksa ID dan akun; ID resource tidak memberi akses lintas pengguna.
PROVIDER_ERROR502Baca ulang status. Jangan retry pembelian upstream secara otomatis.
RECONCILIATION_REQUIRED409Pertahankan hold; baca ulang status. Webhook Tiger dapat memakai HTTP 503 untuk kode ini.
PROVIDER_UNAVAILABLE503Periksa konfigurasi server; lanjutkan pembacaan dengan backoff.
PROVIDER_TIMEOUT504Hasil bisa ambigu. Pertahankan UUID dan hold, tunggu rekonsiliasi.

Batalkan pesanan

POST/api/orders/{id}/cancelSession cookie

Source : app/api/orders/[id]/cancel/route.ts

Pembatalan mengikuti canCancel, cooldown server, dan status provider. Kirim JSON {}. Dana dilepas setelah hasil pembatalan dikonfirmasi, bukan hanya karena tombol ditekan atau timer lokal selesai.

Batalkan pesanan
ParameterTipeWajibKeterangan
id (path)stringYaID order milik pengguna bersesi.

Body wajib: {} dengan Content-Type: application/json. Tidak menerima field tambahan.

POST /api/orders/{id}/cancel · JavaScript
const response = await fetch("/api/orders/a4c4b37c-9b68-4b18-bd52-8e0ea3b08d19/cancel", {
  method: "POST",
  credentials: "same-origin",
  cache: "no-store",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({}),
});
const body = await response.json();

if (!response.ok || !body.ok) {
  throw Object.assign(
    new Error(body.error?.message ?? "Request gagal"),
    { code: body.error?.code, status: response.status },
  );
}

const data = body.data;
Batalkan pesanan
Kode errorHTTPTindakan
NOT_FOUND404Periksa ID dan akun; ID resource tidak memberi akses lintas pengguna.
EARLY_CANCEL_DENIED409Baca ulang order dan ikuti canCancel serta cancelAvailableAt.
INVALID_STATE409GET detail order sebelum menawarkan aksi kembali.
ORDER_ALREADY_TERMINAL409Tampilkan hasil terkini dan perbarui saldo.
RECONCILIATION_REQUIRED409Pertahankan hold; baca ulang status. Webhook Tiger dapat memakai HTTP 503 untuk kode ini.
PROVIDER_TIMEOUT504Hasil bisa ambigu. Pertahankan UUID dan hold, tunggu rekonsiliasi.

Selesaikan pesanan

POST/api/orders/{id}/completeSession cookie

Source : app/api/orders/[id]/complete/route.ts

Menyelesaikan order setelah kode diterima; ikuti canComplete dari server. Kirim JSON {}. Settlement menangkap dana yang ditahan sekali saja. Sesudahnya, revalidasi order, akun, dan ledger.

Selesaikan pesanan
ParameterTipeWajibKeterangan
id (path)stringYaID order milik pengguna bersesi.

Body wajib: {} dengan Content-Type: application/json. Tidak menerima field tambahan.

POST /api/orders/{id}/complete · JavaScript
const response = await fetch("/api/orders/a4c4b37c-9b68-4b18-bd52-8e0ea3b08d19/complete", {
  method: "POST",
  credentials: "same-origin",
  cache: "no-store",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({}),
});
const body = await response.json();

if (!response.ok || !body.ok) {
  throw Object.assign(
    new Error(body.error?.message ?? "Request gagal"),
    { code: body.error?.code, status: response.status },
  );
}

const data = body.data;
Selesaikan pesanan
Kode errorHTTPTindakan
NOT_FOUND404Periksa ID dan akun; ID resource tidak memberi akses lintas pengguna.
INVALID_STATE409GET detail order sebelum menawarkan aksi kembali.
ORDER_ALREADY_TERMINAL409Tampilkan hasil terkini dan perbarui saldo.
RECONCILIATION_REQUIRED409Pertahankan hold; baca ulang status. Webhook Tiger dapat memakai HTTP 503 untuk kode ini.

Schema · Order

Schema · Order
FieldTipeWajibKeterangan
idstringYaSesuai tipe yang ditampilkan.
providertiger | smscodeYatiger = Server 1 (Tiger SMS); smscode = Server 2 (smscode.gg). Katalog, harga, dan pesanan terikat ke server ini; tidak ada perpindahan otomatis.
countryIdstringYaSesuai tipe yang ditampilkan.
serviceIdstringYaSesuai tipe yang ditampilkan.
countryCountryYaLihat schema Country pada OpenAPI.
serviceServiceYaLihat schema Service pada OpenAPI.
phonestringYaNomor, atau teks status ketika nomor belum/tidak diterbitkan. Periksa isPreparing.
priceintegerYaHarga IDR yang dibekukan saat order dibuat.
statuswaiting | completed | cancelled | expired | failedYaStatus DTO client; tidak sama dengan enum database.
createdAtintegerYaUnix timestamp dalam milidetik, bukan detik.
expiresAtinteger | nullYaUnix timestamp dalam milidetik, bukan detik.
codestringTidakOpsional; field tidak dikirim bila belum ada kode terklasifikasi. SMS dapat diterima tanpa field ini. Jangan log OTP produksi.
smsTextstringTidakOpsional; isi SMS, termasuk teks/tautan tanpa kode. Berbeda dari message yang berisi status aplikasi. Jangan log SMS produksi.
canCancelbooleanYaIzin pembatalan pada saat respons dibuat. Server memeriksa ulang provider ketika aksi dikirim.
canCompletebooleanYaTrue pada CODE_RECEIVED, termasuk SMS tanpa kode. Jangan mensyaratkan code untuk menawarkan penyelesaian.
messagestring | nullYaPesan status/kendala yang aman untuk ditampilkan, bukan isi SMS.
isPreparingbooleanYaTrue saat order masih CREATED atau PURCHASING.
cancelAvailableAtinteger | nullYaBatas pembatalan menurut server. Server 1 memakai cooldown lokal; Server 2 mengikuti kemampuan provider (0 bila sudah diizinkan). Null jika bukan ACTIVE atau waktu izin belum diketahui.
Ping! · Panduan yang tumbuh bersama produknya.Bantuan