Payment page (webview)
Cara integrasi paling cepat: Hashpay menyediakan halaman pembayaran siap pakai (hosted payment page) — mirip Snap di Midtrans. Anda cukup membuat order lewat API, lalu membuka url yang dikembalikan. Pelanggan memilih token & wallet di halaman itu, tanpa Anda membangun UI pembayaran sendiri.
Alur
text
1. Ambil credential : merchant_id + API key dari dashboard
2. Buat order (server) : POST /merchant/fiat/order -> dapat "url"
3. Tampilkan ke user : redirect / iframe / in-app webview ke "url"
4. Pelanggan memilih token + wallet dan membayar
5. Anda menerima webhook transaction.success1. Credential
Login ke dashboard.hashpay.id, buat API key di Settings → API Key, dan catat merchant_id Anda. API key hanya dipakai di server Anda.
2. Buat order & dapatkan URL
POST
/merchant/fiat/orderbash
curl -X POST "$HASHPAY_BASE/merchant/fiat/order" \
-H "api-key: $HASHPAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"merchant_id": "10001",
"order_no": "INV-2026-0001",
"amount": "150000",
"name": "Budi Santoso",
"email": "budi@example.com"
}'Respons 201
{
"status_code": 201,
"message": "success",
"data": {
"request": {
"order_no": "INV-2026-0001",
"merchant_id": "10001",
"amount": "150000",
"currency": "IDR",
"status": "Created"
},
"url": "https://webview.hashpay.id/sandbox?key=U2FsdGVkX1...",
"key": "pl_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"expired_at": 1821387856
}
}| Field | Keterangan |
|---|---|
url | Halaman pembayaran siap dibuka. Sudah memuat kredensial terenkripsi untuk order ini. |
key | Kredensial scoped untuk webview (berlaku 30 menit, hanya order ini). Jangan pernah ditampilkan ke browser — sudah tertanam di dalam url. |
3. Tampilkan halaman pembayaran
Pilih sesuai platform Anda:
Redirect (web)
JavaScript
const res = await fetch("/api/checkout", { method: "POST", body: ... });
const { url } = await res.json();
window.location.href = url; // pelanggan menyelesaikan pembayaran lalu kembaliIframe (embed di halaman Anda)
HTML
<iframe
src="https://webview.hashpay.id/sandbox?key=..."
allow="clipboard-write"
style="width: 100%; max-width: 430px; height: 760px; border: 0;"
></iframe>In-app webview (mobile)
React Native
<WebView
source={{ uri: checkoutUrl }}
originWhitelist={["*"]}
javaScriptEnabled
domStorageEnabled
/>4. Ketahui hasilnya
Jangan mengandalkan halaman pengembalian saja — konfirmasi selalu dari webhook (dan/atau polling getOrder):
Webhook transaction.success
{
"event": "transaction.success",
"data": {
"order_no": "INV-2026-0001",
"status": "Success",
"token": "USDT",
"network": "ETHEREUM",
"paid_amount": "8.424753",
"final_amount": "8.340510",
"tx_hash": "0x...",
"link_explorer": "https://sepolia.etherscan.io/tx/0x..."
}
}Detail verifikasi tanda tangan, retry, dan idempotensi ada di Webhooks.
Contoh lengkap (Next.js / Node.js)
Server — buat checkout
// app/api/checkout/route.ts
export async function POST(req: Request) {
const { amount, orderNo } = await req.json();
const res = await fetch(`${process.env.HASHPAY_BASE}/merchant/fiat/order`, {
method: "POST",
headers: {
"api-key": process.env.HASHPAY_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
merchant_id: process.env.HASHPAY_MERCHANT_ID,
order_no: orderNo,
amount: String(amount),
}),
});
const json = await res.json();
if (json.status_code >= 400) {
return Response.json({ message: json.message }, { status: 502 });
}
// Kirim url ke klien; JANGAN kirim data.key
return Response.json({ checkoutUrl: json.data.url });
}Klien — buka halaman pembayaran
const res = await fetch("/api/checkout", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ amount: 150000, orderNo: `INV-${Date.now()}` }),
});
const { checkoutUrl } = await res.json();
window.location.assign(checkoutUrl);Checklist go-live
- Ganti
HASHPAY_BASEkehttps://api.hashpay.id/api/v2/mainnetdan pakai API key produksi. - Set
notification_url(HTTPS) dan verifikasi tanda tangan webhook. - Tangani status
Expired/Underpaiddi sisi Anda. - Jangan simpan
key/urlsecara publik di log atau analytics.