Buat pesanan penerimaan

Membuat pesanan pembayaran bersama dengan jumlah tetap. Responsnya meliputi nomor pesanan, alamat penerima, checkout URL, dan pembayaran status.

notifyUrl diperlukan. Panggilan balik selanjutnya untuk pesanan ini dikirimkan langsung ke URL ini.

POST/openapi/payin/orders

Header

KolomTipeWajibDeskripsi
x-api-keystringYaPedagang API Key. Gunakan nilai yang diawali dengan mch_ dari halaman pengaturan API pedagang.
x-merchant-uidstringYaMerchant UID.
x-timestampstringYa13 digit milidetik timestamp. Penyimpangan jam yang diperbolehkan secara default adalah 5 menit.
x-noncestringYaString acak unik untuk setiap permintaan, hingga 128 karakter. Penggunaan kembali ditolak.
x-signaturestringYaTanda tangan hex dihasilkan dengan HMAC-SHA256. Payload berisi Merchant UID, timestamp, nonce, metode, jalur, query kanonik, dan body kanonik.

Parameter

KolomTipeWajibDeskripsi
chainCodestringYaKode rantai. Nilai yang didukung: TRON / BSC / SOL.
tokenSymbolstringYaSimbol token, misalnya USDT.
merchantOrderNostringYaNomor pesanan pedagang. Maksimal 128 karakter.
amountstringYaJumlah pembayaran, hingga 6 tempat desimal.
notifyUrlstringYaPanggilan balik khusus pesanan URL. Direkomendasikan HTTPS URL publik yang dimiliki oleh pedagang. Maksimal 500 karakter; tujuan jaringan privat, loopback, dan tidak aman dilarang.

Contoh permintaan

{
  "chainCode": "TRON",
  "tokenSymbol": "USDT",
  "merchantOrderNo": "M202604150001",
  "amount": "100.00",
  "notifyUrl": "https://merchant.example.com/api/uugate/payin-notify"
}

Kolom respons

KolomTipeWajibDeskripsi
orderNostringYaNomor pesanan platform.
merchantOrderNostring | nullYaNomor pesanan pedagang.
bindKeystring | nullYaBinding key for exclusive-wallet orders; empty for shared pay-in orders.
chainCodestring | nullYaJaringan pesanan.
tokenSymbolstring | nullYaToken pesanan.
txHashstring | nullYaHash transaksi yang cocok; null sebelum terdeteksi.
amountstring | nullYaJumlah pesanan.
paidAmountstring | nullYaJumlah yang dibayarkan. Kosong sebelum pembayaran.
addressstring | nullYaAlamat penerima sebenarnya.
cashierUrlstring | nullYaURL checkout lengkap dengan token akses acak. Pertahankan seluruh fragmen #ct=.
paymentUristring | nullYaPembayaran dompet URI.
expireAtstring | nullYaWaktu kedaluwarsa pesanan.
createdAtstring | nullYaWaktu yang diciptakan.
detectedAtstring | nullYaPayment detection time; empty before detection.
confirmedAtstring | nullYaOn-chain confirmation time; empty before confirmation.
completedAtstring | nullYaOrder completion time; empty before completion.
statusstringYaPesan status.

Contoh respons

{
  "orderNo": "PI1776193200123ABCD1234",
  "merchantOrderNo": "M202604150001",
  "bindKey": null,
  "amount": "100.000000",
  "paidAmount": null,
  "address": "TXYZ3x9nJ5J4xP2gh6mQW7rT31jB8Y2pA9",
  "cashierUrl": "https://open.uugate.com/SK/PI1776193200123ABCD1234#ct=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "paymentUri": "TRON:TXYZ3x9nJ5J4xP2gh6mQW7rT31jB8Y2pA9?token=USDT&amount=100.000000",
  "expireAt": "2026-04-18T06:30:00.000Z",
  "createdAt": "2026-04-18T06:00:00.000Z",
  "detectedAt": null,
  "confirmedAt": null,
  "completedAt": null,
  "status": "waiting_payment",
  "chainCode": "TRON",
  "tokenSymbol": "USDT",
  "txHash": null
}

Contoh kode

Menjalankan: simpan Java sebagai UUGateExample.java (UUGateCallback.java untuk callback), lalu gunakan java nama file; PHP: php example.php; Go: go run example.go; Node.js: node example.mjs. Verifikasi callback membaca isi asli dari input standar.

import { createHmac, randomBytes } from 'node:crypto';

function required(name) {
  const value = process.env[name]?.trim();
  if (!value) throw new Error(name + ' is required');
  return value;
}
const uid = required("UUGATE_MERCHANT_UID"), key = required("UUGATE_API_KEY");
const timestamp = String(Date.now()), nonce = randomBytes(16).toString("hex");
const method = 'POST', path = '/openapi/payin/orders';
const canonicalQuery = '', canonicalBody = "{\"amount\":\"100.00\",\"chainCode\":\"TRON\",\"merchantOrderNo\":\"M202604150001\",\"notifyUrl\":\"https://merchant.example.com/api/uugate/payin-notify\",\"tokenSymbol\":\"USDT\"}";
const payload = [uid, timestamp, nonce, method, path, canonicalQuery, canonicalBody].join('\n');
const signature = createHmac('sha256', key).update(payload, 'utf8').digest('hex');
const base = (process.env.UUGATE_BASE_URL || 'https://api.uugate.com').replace(/\/+$/, '');
const response = await fetch(base + path, {
  method, redirect: 'error', signal: AbortSignal.timeout(30000),
  headers: { 'Content-Type': 'application/json', 'x-api-key': key, 'x-merchant-uid': uid,
    'x-timestamp': timestamp, 'x-nonce': nonce, 'x-signature': signature },
  ...(canonicalBody ? { body: canonicalBody } : {}),
});
const raw = await response.text();
if (!response.ok) throw new Error('HTTP ' + response.status + ': ' + (raw || 'empty response body'));
JSON.parse(raw);
console.log(raw);

Catatan

  • Pesanan pembayaran bersama dapat memicu 40105 ketika pedagang, jaringan, token, dan jumlah yang sama masih dipesan oleh pesanan lain yang valid.
  • Keempat bahasa memakai jalur, parameter, dan kontrak respons yang sama. Kredensial dibaca dari UUGATE_MERCHANT_UID dan UUGATE_API_KEY; UUGATE_BASE_URL secara default adalah https://api.uugate.com.
  • canonicalBody adalah JSON ringkas dengan nama kolom terurut. Setelah mengubah parameter, urutkan key objek secara rekursif, pertahankan urutan array, dan gunakan UTF-8 tanpa escape tambahan untuk slash atau Unicode. Nominal berupa string; boolean true / false.
  • Respons sukses langsung berisi objek bisnis tanpa pembungkus code / data. Periksa status HTTP sebelum isi. Error bisnis berisi code, message, data, requestId; penolakan keamanan dapat hanya mengirim HTTP 401 / 403 dengan isi kosong.
  • Setelah timeout atau HTTP 5xx, periksa pesanan sebelum mengulang pembuatan atau pengiriman. Buat timestamp, nonce, dan tanda tangan baru untuk setiap permintaan.