Contoh Permintaan dan Verifikasi Tanda Tangan

Metode permintaan: API terutama memakai `GET` / `POST`; permintaan JSON memakai `application/json`.

Autentikasi: permintaan OpenAPI diverifikasi dengan header dan tanda tangan HMAC-SHA256.

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.

Aturan tanda tangan

  • Permintaan menggunakan application/json. Untuk GET APIs tanpa body, bagian body di tanda tangan adalah string kosong.
  • Jalur tanda tangan harus berupa jalur API mentah, misalnya /openapi/payin/orders, tanpa domain.
  • Parameter kueri diurutkan berdasarkan kunci; Kunci JSON body diurutkan sebelum serialisasi.
  • Kegagalan tanda tangan yang umum mencakup timestamp yang kedaluwarsa, nilai nonce yang berulang, urutan bidang yang tidak konsisten, atau spasi tambahan.

Timestamp, nonce, dan kredensial tetap di bawah adalah nilai uji tanda tangan offline. Untuk permintaan nyata, gunakan timestamp milidetik saat ini dan nonce acak baru. Jalur API tidak memiliki awalan versi; v1 hanya merujuk ke tanda tangan callback.

Contoh payload tanda tangan

880001
1776193200000
2f5c7b147c3748f0a8b3d9bb38aa91a4
POST
/openapi/payin/orders

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

Contoh permintaan lengkap

POST /openapi/payin/orders HTTP/1.1
Host: api.uugate.com
Content-Type: application/json
x-api-key: mch_xxxxxxxxxxxxxxxxxxxx
x-merchant-uid: 880001
x-timestamp: 1776193200000
x-nonce: 2f5c7b147c3748f0a8b3d9bb38aa91a4
x-signature: 6d7e96fdbf3ec37c1ec515540f46c6c19b08754973c43293e54644c2da910838

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

Contoh kode tanda tangan

  • 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.

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 = "880001", key = "mch_xxxxxxxxxxxxxxxxxxxx";
const timestamp = "1776193200000", nonce = "2f5c7b147c3748f0a8b3d9bb38aa91a4";
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');
console.log(signature);

Error bisnis mengembalikan JSON berisi code, message, data, dan requestId. Key, tanda tangan, timestamp, nonce yang tidak valid atau pembatasan keamanan dapat mengembalikan HTTP 401 / 403 dengan isi kosong tanpa kode bisnis. Periksa status HTTP dan isi sebelum mengurai JSON. Jangan mengambil keputusan dari teks message yang diterjemahkan.

Kolom error

KolomTipeWajibDeskripsi
codenumberYaKode kesalahan bisnis.
messagestringYaPesan kesalahan.
dataobject | nullYaData kesalahan tambahan.
requestIdstring | nullYaID jejak permintaan server.

Contoh error

HTTP/1.1 401 Unauthorized
Cache-Control: no-store
Content-Length: 0